From 264086dcb7e14c3e5ad5cf4da7d016e842094692 Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:45:53 -0400 Subject: [PATCH 1/4] chore: snapshot of mainnet-deployed contract versions (April 2026) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contracts fetched from mainnet (0x1e4aa0b87d10b141, 0x93c18b0282a6b82c, 0xf1ab99c82dee3526) via flow CLI for upgrade review. DO NOT MERGE — this branch is used as the base of a review PR to show the diff between the currently deployed mainnet contracts and main. --- cadence/contracts/bridge/FlowEVMBridge.cdc | 182 +++---- .../bridge/FlowEVMBridgeAccessor.cdc | 51 +- .../contracts/bridge/FlowEVMBridgeConfig.cdc | 18 +- .../FlowEVMBridgeCustomAssociationTypes.cdc | 8 +- .../FlowEVMBridgeCustomAssociations.cdc | 10 +- .../bridge/FlowEVMBridgeHandlers.cdc | 80 +-- .../bridge/FlowEVMBridgeNFTEscrow.cdc | 18 +- .../bridge/FlowEVMBridgeResolver.cdc | 18 +- .../bridge/FlowEVMBridgeTemplates.cdc | 8 +- .../bridge/FlowEVMBridgeTokenEscrow.cdc | 24 +- .../contracts/bridge/FlowEVMBridgeUtils.cdc | 497 +++++++----------- .../bridge/interfaces/CrossVMNFT.cdc | 10 +- .../bridge/interfaces/CrossVMToken.cdc | 4 +- .../FlowEVMBridgeHandlerInterfaces.cdc | 22 +- .../contracts/bridge/interfaces/ICrossVM.cdc | 2 +- .../bridge/interfaces/ICrossVMAsset.cdc | 4 +- .../bridge/interfaces/IEVMBridgeNFTMinter.cdc | 2 +- .../interfaces/IEVMBridgeTokenMinter.cdc | 2 +- .../bridge/interfaces/IFlowEVMNFTBridge.cdc | 15 +- .../bridge/interfaces/IFlowEVMTokenBridge.cdc | 11 +- .../contracts/example-assets/ExampleNFT.cdc | 6 +- .../contracts/example-assets/ExampleToken.cdc | 6 +- cadence/contracts/handled-tokens/USDCFlow.cdc | 63 +-- cadence/contracts/utils/ScopedFTProviders.cdc | 4 +- cadence/contracts/utils/Serialize.cdc | 6 +- cadence/contracts/utils/SerializeMetadata.cdc | 10 +- cadence/contracts/utils/StringUtils.cdc | 2 +- 27 files changed, 480 insertions(+), 603 deletions(-) diff --git a/cadence/contracts/bridge/FlowEVMBridge.cdc b/cadence/contracts/bridge/FlowEVMBridge.cdc index 7c321670..7a8b8287 100644 --- a/cadence/contracts/bridge/FlowEVMBridge.cdc +++ b/cadence/contracts/bridge/FlowEVMBridge.cdc @@ -1,30 +1,30 @@ -import "Burner" -import "FungibleToken" -import "FungibleTokenMetadataViews" -import "NonFungibleToken" -import "MetadataViews" -import "CrossVMMetadataViews" -import "ViewResolver" - -import "EVM" - -import "IBridgePermissions" -import "ICrossVM" -import "IEVMBridgeNFTMinter" -import "IEVMBridgeTokenMinter" -import "IFlowEVMNFTBridge" -import "IFlowEVMTokenBridge" -import "CrossVMNFT" -import "CrossVMToken" -import "FlowEVMBridgeCustomAssociationTypes" -import "FlowEVMBridgeCustomAssociations" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeHandlerInterfaces" -import "FlowEVMBridgeUtils" -import "FlowEVMBridgeNFTEscrow" -import "FlowEVMBridgeTokenEscrow" -import "FlowEVMBridgeTemplates" -import "SerializeMetadata" +import Burner from 0xf233dcee88fe0abe +import FungibleToken from 0xf233dcee88fe0abe +import FungibleTokenMetadataViews from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 +import MetadataViews from 0x1d7e57aa55817448 +import CrossVMMetadataViews from 0x1d7e57aa55817448 +import ViewResolver from 0x1d7e57aa55817448 + +import EVM from 0xe467b9dd11fa00df + +import IBridgePermissions from 0x1e4aa0b87d10b141 +import ICrossVM from 0x1e4aa0b87d10b141 +import IEVMBridgeNFTMinter from 0x1e4aa0b87d10b141 +import IEVMBridgeTokenMinter from 0x1e4aa0b87d10b141 +import IFlowEVMNFTBridge from 0x1e4aa0b87d10b141 +import IFlowEVMTokenBridge from 0x1e4aa0b87d10b141 +import CrossVMNFT from 0x1e4aa0b87d10b141 +import CrossVMToken from 0x1e4aa0b87d10b141 +import FlowEVMBridgeCustomAssociationTypes from 0x1e4aa0b87d10b141 +import FlowEVMBridgeCustomAssociations from 0x1e4aa0b87d10b141 +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import FlowEVMBridgeHandlerInterfaces from 0x1e4aa0b87d10b141 +import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 +import FlowEVMBridgeNFTEscrow from 0x1e4aa0b87d10b141 +import FlowEVMBridgeTokenEscrow from 0x1e4aa0b87d10b141 +import FlowEVMBridgeTemplates from 0x1e4aa0b87d10b141 +import SerializeMetadata from 0x1e4aa0b87d10b141 /// The FlowEVMBridge contract is the main entrypoint for bridging NFT & FT assets between Flow & FlowEVM. /// @@ -75,10 +75,10 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { pre { !FlowEVMBridgeConfig.isPaused(): "Bridge operations are currently paused" !FlowEVMBridgeConfig.isCadenceTypeBlocked(type): - "This Cadence Type \(type.identifier) is currently blocked from being onboarded" + "This Cadence Type ".concat(type.identifier).concat(" is currently blocked from being onboarded") self.typeRequiresOnboarding(type) == true: "Onboarding is not needed for this type" FlowEVMBridgeUtils.typeAllowsBridging(type): - "This Cadence Type \(type.identifier) is currently opted-out of bridge onboarding" + "This Cadence Type ".concat(type.identifier).concat(" is currently opted-out of bridge onboarding") FlowEVMBridgeUtils.isCadenceNative(type: type): "Only Cadence-native assets can be onboarded by Type" } /* Custom cross-VM Implementation check */ @@ -115,7 +115,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { let vault <-createVaultFunction(type) assert( vault.getType() == type, - message: "Requested to onboard type=\(type.identifier) but contract returned type=\(vault.getType().identifier)" + message: "Requested to onboard type=".concat(type.identifier).concat( "but contract returned type=").concat(vault.getType().identifier) ) FlowEVMBridgeTokenEscrow.initializeEscrow( with: <-vault, @@ -125,7 +125,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { evmTokenAddress: onboardingValues.evmContractAddress ) } else { - panic("Attempted to onboard unsupported type: \(type.identifier)") + panic("Attempted to onboard unsupported type: ".concat(type.identifier)) } /* Confirmation */ @@ -157,7 +157,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { pre { !FlowEVMBridgeConfig.isPaused(): "Bridge operations are currently paused" !FlowEVMBridgeConfig.isEVMAddressBlocked(address): - "This EVM contract \(address.toString()) is currently blocked from being onboarded" + "This EVM contract ".concat(address.toString()).concat(" is currently blocked from being onboarded") } /* Custom cross-VM Implementation check */ // @@ -216,13 +216,18 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { !FlowEVMBridgeConfig.isCadenceTypeBlocked(type): "Type \(type.identifier) has been blocked from onboarding" FlowEVMBridgeUtils.isCadenceNative(type: type): - "Attempting to register a bridge-deployed NFT - cannot update a bridge-defined asset. If updating your EVM contract's Cadence association, deploy your Cadence NFT contract and register using the newly defined Cadence type" + "Attempting to register a bridge-deployed NFT - cannot update a bridge-defined asset. If updating your EVM " + .concat("contract's Cadence association, deploy your Cadence NFT contract and register using the newly defined Cadence type") FlowEVMBridgeCustomAssociations.getEVMAddressAssociated(with: type) == nil: - "A custom association has already been declared for type \(type.identifier) with EVM address \(FlowEVMBridgeCustomAssociations.getEVMAddressAssociated(with: type)!.toString()). Custom associations can only be declared once for any given Cadence Type or EVM contract" + "A custom association has already been declared for type \(type.identifier) with EVM address " + .concat(FlowEVMBridgeCustomAssociations.getEVMAddressAssociated(with: type)!.toString()) + .concat(". Custom associations can only be declared once for any given Cadence Type or EVM contract") fulfillmentMinter?.check() ?? true: - "NFTFulfillmentMinter Capability is invalid - Issue a new Capability and try again" + "NFTFulfillmentMinter Capability is invalid - Issue a new " + .concat("Capability and try again") fulfillmentMinter != nil ? fulfillmentMinter!.borrow()!.getType().address! == type.address! : true: - "NFTFulfillmentMinter must be defined by a contract deployed to the registered type address \(type.address!) but found defining address of \(fulfillmentMinter!.borrow()!.getType().address!)" + "NFTFulfillmentMinter must be defined by a contract deployed to the registered type address \(type.address!) " + .concat(" but found defining address of \(fulfillmentMinter!.borrow()!.getType().address!)") } /* Provision fees */ // @@ -243,12 +248,15 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { ) assert( FlowEVMBridgeCustomAssociations.getTypeAssociated(with: evmPointer.evmContractAddress) == nil, - message: "A custom association has already been declared for EVM address \(evmPointer.evmContractAddress.toString()) with Cadence Type \(FlowEVMBridgeCustomAssociations.getTypeAssociated(with: evmPointer.evmContractAddress)?.identifier ?? ""). Custom associations can only be declared once for any given Cadence Type or EVM contract" + message: "A custom association has already been declared for EVM address \(evmPointer.evmContractAddress.toString()) with Cadence Type " + .concat(FlowEVMBridgeCustomAssociations.getTypeAssociated(with: evmPointer.evmContractAddress)?.identifier ?? "") + .concat(". Custom associations can only be declared once for any given Cadence Type or EVM contract") ) assert( FlowEVMBridgeUtils.isERC721(evmContractAddress: evmPointer.evmContractAddress) && !FlowEVMBridgeUtils.isERC20(evmContractAddress: evmPointer.evmContractAddress), - message: "Cross-VM NFTs must be implemented as ERC721 exclusively, but detected an invalid EVM interface at EVM contract \(evmPointer.evmContractAddress.toString())" + message: "Cross-VM NFTs must be implemented as ERC721 exclusively, but detected an invalid EVM interface " + .concat("at EVM contract \(evmPointer.evmContractAddress.toString())") ) // Get pointer on EVM side @@ -274,11 +282,15 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { // Check supportsInterface() for CrossVMBridgeERC721Fulfillment if NFT is Cadence-native if evmPointer.nativeVM == CrossVMMetadataViews.VM.Cadence { assert(FlowEVMBridgeUtils.supportsCadenceNativeNFTEVMInterfaces(evmContract: evmPointer.evmContractAddress), - message: "Corresponding EVM contract does not implement necessary EVM interfaces ICrossVMBridgeERC721Fulfillment and/or ICrossVMBridgeCallable. All Cadence-native cross-VM NFTs must implement these interfaces and grant the bridge COA the ability to fulfill bridge requests moving NFTs into EVM.") + message: "Corresponding EVM contract does not implement necessary EVM interfaces ICrossVMBridgeERC721Fulfillment " + .concat("and/or ICrossVMBridgeCallable. All Cadence-native cross-VM NFTs must implement these interfaces and ") + .concat("grant the bridge COA the ability to fulfill bridge requests moving NFTs into EVM.")) let designatedVMBridgeAddress = FlowEVMBridgeUtils.getVMBridgeAddressFromICrossVMBridgeCallable(evmContract: evmPointer.evmContractAddress) - ?? panic("Could not recover declared VM bridge address from EVM contract \(evmPointer.evmContractAddress.toString()). Ensure the contract conforms to ICrossVMBridgeCallable and declare the vmBridgeAddress as \(FlowEVMBridgeUtils.getBridgeCOAEVMAddress().toString())") + ?? panic("Could not recover declared VM bridge address from EVM contract \(evmPointer.evmContractAddress.toString()). " + .concat("Ensure the contract conforms to ICrossVMBridgeCallable and declare the vmBridgeAddress as \(FlowEVMBridgeUtils.getBridgeCOAEVMAddress().toString())")) assert(designatedVMBridgeAddress.equals(FlowEVMBridgeUtils.getBridgeCOAEVMAddress()), - message: "ICrossVMBridgeCallable declared \(designatedVMBridgeAddress.toString()) as vmBridgeAddress which must be declared as \(FlowEVMBridgeUtils.getBridgeCOAEVMAddress().toString())") + message: "ICrossVMBridgeCallable declared \(designatedVMBridgeAddress.toString())" + .concat(" as vmBridgeAddress which must be declared as \(FlowEVMBridgeUtils.getBridgeCOAEVMAddress().toString())")) } /* Native VM consistency check */ @@ -287,14 +299,21 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { let legacyEVMAssoc = FlowEVMBridgeConfig.getLegacyEVMAddressAssociated(with: type) let legacyCadenceAssoc = FlowEVMBridgeConfig.getLegacyTypeAssociated(with: evmPointer.evmContractAddress) assert(legacyEVMAssoc == nil || legacyCadenceAssoc == nil, - message: "Both the EVM contract \(evmPointer.evmContractAddress.toString()) and the Cadence Type \(type.identifier) have already been onboarded to the VM bridge - one side of this association will have to be redeployed and the declared association updated to a non-onboarded target in order to register as a custom cross-VM asset.") + message: "Both the EVM contract \(evmPointer.evmContractAddress.toString()) and the Cadence Type \(type.identifier) " + .concat("have already been onboarded to the VM bridge - one side of this association will have to be redeployed ") + .concat("and the declared association updated to a non-onboarded target in order to register as a custom cross-VM asset.")) // Ensure the native VM is consistent if the NFT has been previously onboarded via the permissionless path if legacyEVMAssoc != nil { assert(evmPointer.nativeVM == CrossVMMetadataViews.VM.Cadence, - message: "Attempting to register NFT \(type.identifier) as EVM-native after it has already been onboarded as Cadence-native. This NFT must be configured as Cadence-native with an ERC721 implementing CrossVMBridgeERC721Fulfillment base contract allowing the bridge to fulfill NFTs moving into EVM") + message: "Attempting to register NFT \(type.identifier) as EVM-native after it has already been " + .concat("onboarded as Cadence-native. This NFT must be configured as Cadence-native with an ERC721 ") + .concat("implementing CrossVMBridgeERC721Fulfillment base contract allowing the bridge to fulfill ") + .concat("NFTs moving into EVM")) } else if legacyCadenceAssoc != nil { assert(evmPointer.nativeVM == CrossVMMetadataViews.VM.EVM, - message: "Attempting to register NFT \(type.identifier) as Cadence-native after it has already been onboarded as EVM-native. This NFT must be configured as EVM-native and provide an NFTFulfillmentMinter Capability so the bridge may fulfill NFTs moving into Cadence.") + message: "Attempting to register NFT \(type.identifier) as Cadence-native after it has already been " + .concat("onboarded as EVM-native. This NFT must be configured as EVM-native and provide an NFTFulfillmentMinter ") + .concat("Capability so the bridge may fulfill NFTs moving into Cadence.")) } FlowEVMBridgeCustomAssociations.saveCustomAssociation( @@ -375,7 +394,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { type: Type, id: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (EVM.EVMAddress): EVM.ResultDecoded + protectedTransferCall: fun (EVM.EVMAddress): EVM.Result ): @{NonFungibleToken.NFT} { pre { !FlowEVMBridgeConfig.isPaused(): "Bridge operations are currently paused" @@ -387,7 +406,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { let customAssocByType = FlowEVMBridgeCustomAssociations.getEVMAddressAssociated(with: type) let customAssocByEVMAddr = bridgedAssoc != nil ? FlowEVMBridgeCustomAssociations.getTypeAssociated(with: bridgedAssoc!) : nil // Initialize the internal handler method that will be used to move the NFT from EVM - var handler: (fun (EVM.EVMAddress, Type, UInt256, auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, fun (EVM.EVMAddress): EVM.ResultDecoded): @{NonFungibleToken.NFT})? = nil + var handler: (fun (EVM.EVMAddress, Type, UInt256, auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, fun (EVM.EVMAddress): EVM.Result): @{NonFungibleToken.NFT})? = nil if bridgedAssoc != nil && customAssocByType == nil && customAssocByEVMAddr == nil { // Common case - bridge-defined counterpart in non-native VM handler = self.handleDefaultNFTFromEVM @@ -513,7 +532,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { type: Type, amount: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (): EVM.ResultDecoded + protectedTransferCall: fun (): EVM.Result ): @{FungibleToken.Vault} { pre { !FlowEVMBridgeConfig.isPaused(): "Bridge operations are currently paused" @@ -579,13 +598,12 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { message: "Unexpected error bridging FT from EVM" ) // Burn the EVM tokens that have now been transferred to the bridge in EVM - let burnResult = FlowEVMBridgeUtils.callWithSigAndArgs( + let burnResult: EVM.Result = FlowEVMBridgeUtils.call( signature: "burn(uint256)", targetEVMAddress: associatedAddress, args: [amount], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert(burnResult.status == EVM.Status.successful, message: "Burn of EVM tokens failed") @@ -824,7 +842,8 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { to: EVM.EVMAddress, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}) { let evmPointer = FlowEVMBridgeCustomAssociations.getEVMPointerAsRegistered(forType: token.getType()) - ?? panic("Could not find custom association for cross-VM NFT \(token.getType().identifier) with id \(token.id). Ensure this NFT has been registered as a cross-VM.") + ?? panic("Could not find custom association for cross-VM NFT \(token.getType().identifier) with id \(token.id). " + .concat("Ensure this NFT has been registered as a cross-VM.")) return evmPointer.nativeVM == CrossVMMetadataViews.VM.Cadence ? self.handleCadenceNativeCrossVMNFTToEVM(token: <-token, to: to, feeProvider: feeProvider) : self.handleEVMNativeCrossVMNFTToEVM(token: <-token, to: to, feeProvider: feeProvider) @@ -898,17 +917,9 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { } let bridgedAssociation = FlowEVMBridgeConfig.getLegacyEVMAddressAssociated(with: token.getType())! let updatedCadenceAssociation = FlowEVMBridgeCustomAssociations.getTypeAssociated(with: bridgedAssociation) - ?? panic("Could not find a custom cross-VM association for NFT \(token.getType().identifier) #\(token.id). The handleUpdatedBridgedNFTToEVM route is intended for bridged Cadence NFTs associated with ERC721 contracts that have registered as a custom cross-VM NFT collection.") - - // Ensure the updated/custom type is not paused - the top-level pause check only covers the - // caller-supplied bridge-defined type, so we must re-check here after resolving the migration target - assert(FlowEVMBridgeConfig.isTypePaused(updatedCadenceAssociation) == false, - message: "Bridging is currently paused for type \(updatedCadenceAssociation.identifier)") - - // The force-casts to CrossVMNFT.EVMNFT below are safe: this handler is only reached when the token is a - // bridge-defined NFT (pre-condition enforces !isCadenceNative). All bridge-defined NFTs are deployed from - // the bridge's template contract, which unconditionally implements CrossVMNFT.EVMNFT. No user-controlled - // contract can produce a bridge-defined type, so these casts cannot fail in practice. + ?? panic("Could not find a custom cross-VM association for NFT \(token.getType().identifier) #\(token.id). " + .concat("The handleUpdatedBridgedNFTToEVM route is intended for bridged Cadence NFTs associated with ") + .concat(" ERC721 contracts that have registered as a custom cross-VM NFT collection.")) let tokenRef = (&token as &{NonFungibleToken.NFT}) as! &{CrossVMNFT.EVMNFT} let evmID = tokenRef.evmID let bridgedToken <- token as! @{CrossVMNFT.EVMNFT} @@ -920,8 +931,6 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { erc721Address: bridgedAssociation.toString() ) Burner.burn(<-bridgedToken) - // No bridge fee is charged here. The bridge burns the legacy Cadence NFT and releases the ERC721 from - // EVM-side escrow — no new assets are added to bridge storage, so no storage cost is incurred. // Transfer the ERC721 from escrow to the named recipient FlowEVMBridgeUtils.mustSafeTransferERC721(erc721Address: bridgedAssociation, to: to, id: evmID) } @@ -934,7 +943,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { type: Type, id: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (EVM.EVMAddress): EVM.ResultDecoded + protectedTransferCall: fun (EVM.EVMAddress): EVM.Result ): @{NonFungibleToken.NFT} { /* Provision fee */ // @@ -996,10 +1005,11 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { type: Type, id: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (EVM.EVMAddress): EVM.ResultDecoded + protectedTransferCall: fun (EVM.EVMAddress): EVM.Result ): @{NonFungibleToken.NFT} { let evmPointer = FlowEVMBridgeCustomAssociations.getEVMPointerAsRegistered(forType: type) - ?? panic("Could not find custom association for cross-VM NFT \(type.identifier) with id \(id). Ensure this NFT has been registered as a cross-VM.") + ?? panic("Could not find custom association for cross-VM NFT \(type.identifier) with id \(id). " + .concat("Ensure this NFT has been registered as a cross-VM.")) if evmPointer.nativeVM == CrossVMMetadataViews.VM.Cadence { return <- self.handleCadenceNativeCrossVMNFTFromEVM( owner: owner, @@ -1027,7 +1037,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { type: Type, id: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (EVM.EVMAddress): EVM.ResultDecoded + protectedTransferCall: fun (EVM.EVMAddress): EVM.Result ): @{NonFungibleToken.NFT} { pre { FlowEVMBridgeUtils.isCadenceNative(type: type): @@ -1061,7 +1071,9 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { ) } else { // Bridged token not wrapped nor owned by caller - could not determine owner - panic("Bridged ERC721 \(bridgedAssociation!.toString()) ID \(id) still exists after \(type.identifier) was updated to associate with ERC721 \(customERC721.toString()), but the bridged token is neither wrapped nor owned by caller \(owner.toString()). Could not determine owner.") + panic("Bridged ERC721 \(bridgedAssociation!.toString()) ID \(id) still exists after \(type.identifier) " + .concat("was updated to associate with ERC721 \(customERC721.toString()), but the bridged token is ") + .concat("neither wrapped nor owned by caller \(owner.toString()). Could not determine owner.")) } // Burn the bridged ERC721, taking the bridged representation out of circulation in favor of custom ERC721 FlowEVMBridgeUtils.mustBurnERC721(erc721Address: bridgedAssociation!, id: id) @@ -1073,30 +1085,22 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { protectedTransferCall: protectedTransferCall ) } - // No bridge fee is charged here. The bridge is releasing a Cadence-native NFT from existing escrow — the - // storage cost was already accounted for when the NFT was escrowed on the ToEVM path. Unlocking reduces - // bridge storage rather than increasing it, so no new fee is warranted. // Cadence-native NFTs must be in escrow, so unlock & return - let lockedCadenceID = FlowEVMBridgeNFTEscrow.getLockedCadenceID(type: type, evmID: id) - ?? panic("NFT of type \(type.identifier) with EVM ID \(id) is not in escrow — cannot bridge from EVM") - return <-FlowEVMBridgeNFTEscrow.unlockNFT(type: type, id: lockedCadenceID) + return <-FlowEVMBridgeNFTEscrow.unlockNFT( + type: type, + id: FlowEVMBridgeNFTEscrow.getLockedCadenceID(type: type, evmID: id)! + ) } /// Handler to move registered cross-VM EVM-native NFTs from EVM /// - /// Note on `_type` vs `type`: this handler is only reached via `handleCrossVMNFTFromEVM`, which is dispatched - /// when `customAssocByType != nil` — meaning the caller-supplied `type` is always the custom cross-VM type, - /// not a legacy bridge-defined type. Therefore `isCadenceNative(type)` is always true for this handler, the - /// `if !isCadenceNative` branch below is never entered, and `_type` is never reassigned away from `type`. - /// The `isLocked` check and the `unlockNFT`/`fulfillNFTFromEVM` calls therefore always use the same type. - /// access(self) fun handleEVMNativeCrossVMNFTFromEVM( owner: EVM.EVMAddress, type: Type, id: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (EVM.EVMAddress): EVM.ResultDecoded + protectedTransferCall: fun (EVM.EVMAddress): EVM.Result ): @{NonFungibleToken.NFT} { pre { id <= UInt256(UInt64.max): @@ -1126,9 +1130,6 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { FlowEVMBridgeUtils.mustEscrowERC721(owner: owner, id: id, erc721Address: erc721Address, protectedTransferCall: protectedTransferCall) - // No bridge fee is charged here. EVM-native NFTs are fulfilled either by unlocking from existing Cadence - // escrow (reducing bridge storage) or by minting via the project-provided NFTFulfillmentMinter (no bridge - // storage involved). In neither case does the bridge account incur a new storage cost. if FlowEVMBridgeNFTEscrow.isLocked(type: type, id: UInt64(id)) { // Unlock the NFT from escrow return <-FlowEVMBridgeNFTEscrow.unlockNFT(type: _type, id: UInt64(id)) @@ -1144,7 +1145,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { type: Type, id: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (EVM.EVMAddress): EVM.ResultDecoded + protectedTransferCall: fun (EVM.EVMAddress): EVM.Result ): @{NonFungibleToken.NFT} { pre { !FlowEVMBridgeUtils.isCadenceNative(type: type): // expect this type to be bridge-defined @@ -1156,11 +1157,6 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { let bridgedAssoc = FlowEVMBridgeConfig.getLegacyEVMAddressAssociated(with: type)! let updatedTypeAssoc = FlowEVMBridgeConfig.getTypeAssociated(with: bridgedAssoc)! - // Ensure the updated/custom type is not paused - the top-level pause check only covers the - // caller-supplied legacy type, so we must re-check here after resolving the migration target - assert(FlowEVMBridgeConfig.isTypePaused(updatedTypeAssoc) == false, - message: "Bridging is currently paused for type \(updatedTypeAssoc.identifier)") - // Confirm custom association is EVM-native let configInfo = FlowEVMBridgeCustomAssociations.getCustomConfigInfo(forType: updatedTypeAssoc)! assert(configInfo.evmPointer.nativeVM == CrossVMMetadataViews.VM.EVM, @@ -1180,10 +1176,6 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { ) Burner.burn(<-bridgedToken) } - // No bridge fee is charged here. The legacy bridge-defined NFT (if present in escrow) is burned, and the - // custom type NFT is either unlocked from existing escrow or minted via the project's NFTFulfillmentMinter. - // In all cases the bridge is releasing or burning assets rather than storing new ones, so no storage cost - // is incurred and no fee is warranted. // Either unlock if locked or fulfill via configured NFTFulfillmentMinter if FlowEVMBridgeNFTEscrow.isLocked(type: updatedTypeAssoc, id: UInt64(id)) { return <- FlowEVMBridgeNFTEscrow.unlockNFT(type: updatedTypeAssoc, id: UInt64(id)) diff --git a/cadence/contracts/bridge/FlowEVMBridgeAccessor.cdc b/cadence/contracts/bridge/FlowEVMBridgeAccessor.cdc index c6394d8e..7532bd76 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeAccessor.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeAccessor.cdc @@ -1,12 +1,11 @@ -import "NonFungibleToken" -import "FungibleToken" -import "FlowToken" +import NonFungibleToken from 0x1d7e57aa55817448 +import FungibleToken from 0xf233dcee88fe0abe +import FlowToken from 0x1654653399040a61 -import "EVM" +import EVM from 0xe467b9dd11fa00df -import "FlowEVMBridgeConfig" -import "FlowEVMBridge" -import "FlowEVMBridgeUtils" +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import FlowEVMBridge from 0x1e4aa0b87d10b141 /// This contract defines a mechanism for routing bridge requests from the EVM contract to the Flow-EVM bridge contract /// @@ -53,7 +52,7 @@ contract FlowEVMBridgeAccessor { ): @{NonFungibleToken.NFT} { // Define a callback function, enabling the bridge to act on the ephemeral COA reference in scope var executed = false - fun callback(target: EVM.EVMAddress): EVM.ResultDecoded { + fun callback(target: EVM.EVMAddress): EVM.Result { pre { !executed: "Callback can only be executed once" FlowEVMBridge.getAssociatedEVMAddress(with: type) ?? FlowEVMBridgeConfig.getLegacyEVMAddressAssociated(with: type) != nil: @@ -69,13 +68,14 @@ contract FlowEVMBridgeAccessor { message: "Target EVM contract \(target.toString()) is not association with NFT Type \(type.identifier) - COA `safeTransferFrom` callback rejected") executed = true - return caller.callWithSigAndArgs( + return caller.call( to: target, - signature: "safeTransferFrom(address,address,uint256)", - args: [caller.address(), FlowEVMBridge.getBridgeCOAEVMAddress(), id], + data: EVM.encodeABIWithSignature( + "safeTransferFrom(address,address,uint256)", + [caller.address(), FlowEVMBridge.getBridgeCOAEVMAddress(), id] + ), gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0, - resultTypes: nil + value: EVM.Balance(attoflow: 0) ) } // Execute the bridge request @@ -119,16 +119,9 @@ contract FlowEVMBridgeAccessor { amount: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider} ): @{FungibleToken.Vault} { - // Resolve the EVM address associated with the token type - let associatedEVMAddress = FlowEVMBridge.getAssociatedEVMAddress(with: type) - ?? panic("No EVM address associated with type") - // Round the requested ERC20 amount down to the maximum precision representable by UFix64 to ensure the - // amount escrowed on the EVM side matches exactly what will be minted or unlocked on the Cadence side, - // preventing sub-UFix64-precision "dust" from being permanently locked in escrow. - let roundedAmount = FlowEVMBridgeUtils.castERC20AmountToCadencePrecision(amount, erc20Address: associatedEVMAddress) // Define a callback function, enabling the bridge to act on the ephemeral COA reference in scope var executed = false - fun callback(): EVM.ResultDecoded { + fun callback(): EVM.Result { pre { !executed: "Callback can only be executed once" } @@ -136,20 +129,22 @@ contract FlowEVMBridgeAccessor { executed: "Callback must be executed" } executed = true - return caller.callWithSigAndArgs( - to: associatedEVMAddress, - signature: "transfer(address,uint256)", - args: [FlowEVMBridge.getBridgeCOAEVMAddress(), roundedAmount], + return caller.call( + to: FlowEVMBridge.getAssociatedEVMAddress(with: type) + ?? panic("No EVM address associated with type"), + data: EVM.encodeABIWithSignature( + "transfer(address,uint256)", + [FlowEVMBridge.getBridgeCOAEVMAddress(), amount] + ), gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0, - resultTypes: nil + value: EVM.Balance(attoflow: 0) ) } // Execute the bridge request return <- FlowEVMBridge.bridgeTokensFromEVM( owner: caller.address(), type: type, - amount: roundedAmount, + amount: amount, feeProvider: feeProvider, protectedTransferCall: callback ) diff --git a/cadence/contracts/bridge/FlowEVMBridgeConfig.cdc b/cadence/contracts/bridge/FlowEVMBridgeConfig.cdc index 534e5cef..01eb72c8 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeConfig.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeConfig.cdc @@ -1,8 +1,8 @@ -import "EVM" -import "NonFungibleToken" +import EVM from 0xe467b9dd11fa00df +import NonFungibleToken from 0x1d7e57aa55817448 -import "FlowEVMBridgeHandlerInterfaces" -import "FlowEVMBridgeCustomAssociations" +import FlowEVMBridgeHandlerInterfaces from 0x1e4aa0b87d10b141 +import FlowEVMBridgeCustomAssociations from 0x1e4aa0b87d10b141 /// This contract is used to store configuration information shared by FlowEVMBridge contracts /// @@ -101,14 +101,8 @@ contract FlowEVMBridgeConfig { return self.paused } - /// Returns whether operations for a given Type are paused. - /// - /// Note: the return type is `Bool?` for API compatibility, but this function currently always returns a - /// non-nil `Bool`. The three sub-expressions all produce concrete `Bool` values via nil-coalescing or direct - /// comparison. A `nil` return cannot occur under current logic. Call sites should use `== false` (rather than - /// `!= true`) so that a hypothetical future `nil` is treated conservatively as "paused" rather than - /// "not paused". The doc comment claim that `nil` means "not yet onboarded" does not reflect actual behavior - /// and is retained only for historical reference. + /// Returns whether operations for a given Type are paused. A return value of nil indicates the Type is not yet + /// onboarded to the bridge. /// access(all) view fun isTypePaused(_ type: Type): Bool? { diff --git a/cadence/contracts/bridge/FlowEVMBridgeCustomAssociationTypes.cdc b/cadence/contracts/bridge/FlowEVMBridgeCustomAssociationTypes.cdc index fae6c727..715833f0 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeCustomAssociationTypes.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeCustomAssociationTypes.cdc @@ -1,7 +1,7 @@ -import "FungibleToken" -import "NonFungibleToken" -import "CrossVMMetadataViews" -import "EVM" +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 +import CrossVMMetadataViews from 0x1d7e57aa55817448 +import EVM from 0xe467b9dd11fa00df /// This contract defines types required for custom cross-VM associations as used in FlowEVMBridgeCustomAssociation /// and in EVM-native cross-VM NFTs. diff --git a/cadence/contracts/bridge/FlowEVMBridgeCustomAssociations.cdc b/cadence/contracts/bridge/FlowEVMBridgeCustomAssociations.cdc index e7d79221..9f735b1b 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeCustomAssociations.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeCustomAssociations.cdc @@ -1,8 +1,8 @@ -import "NonFungibleToken" -import "CrossVMMetadataViews" -import "EVM" +import NonFungibleToken from 0x1d7e57aa55817448 +import CrossVMMetadataViews from 0x1d7e57aa55817448 +import EVM from 0xe467b9dd11fa00df -import "FlowEVMBridgeCustomAssociationTypes" +import FlowEVMBridgeCustomAssociationTypes from 0x1e4aa0b87d10b141 /// The FlowEVMBridgeCustomAssociations is tasked with preserving custom associations between Cadence assets and their /// EVM implementations. These associations should be validated before `saveCustomAssociation` is called by @@ -128,7 +128,7 @@ access(all) contract FlowEVMBridgeCustomAssociations { type.isSubtype(of: Type<@{NonFungibleToken.NFT}>()): "Only NFT cross-VM associations are currently supported but \(type.identifier) is not an NFT implementation" self.associationsByEVMAddress[evmContractAddress.toString()] == nil: - "EVM Address \(evmContractAddress.toString()) already has a custom association with \(self.associationsByEVMAddress[evmContractAddress.toString()]!.identifier)" + "EVM Address \(evmContractAddress.toString()) already has a custom association with \(self.borrowNFTCustomConfig(forType: type)!.getCadenceType().identifier)" fulfillmentMinter?.check() ?? true: "The NFTFulfillmentMinter Capability issued from \(fulfillmentMinter!.address.toString()) is invalid. Ensure the Capability is properly issued and active." } diff --git a/cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc b/cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc index f29f587d..fb922546 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc @@ -1,13 +1,13 @@ -import "Burner" -import "FungibleToken" -import "NonFungibleToken" -import "FlowToken" +import Burner from 0xf233dcee88fe0abe +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 +import FlowToken from 0x1654653399040a61 -import "EVM" +import EVM from 0xe467b9dd11fa00df -import "FlowEVMBridgeHandlerInterfaces" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" +import FlowEVMBridgeHandlerInterfaces from 0x1e4aa0b87d10b141 +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 /// FlowEVMBridgeHandlers /// @@ -105,7 +105,7 @@ access(all) contract FlowEVMBridgeHandlers { let amount = tokens.balance let uintAmount = FlowEVMBridgeUtils.convertCadenceAmountToERC20Amount(amount, erc20Address: evmAddress) - assert(uintAmount > 0, message: "Amount to bridge must be greater than 0") + assert(uintAmount > UInt256(0), message: "Amount to bridge must be greater than 0") Burner.burn(<-tokens) @@ -127,7 +127,7 @@ access(all) contract FlowEVMBridgeHandlers { owner: EVM.EVMAddress, type: Type, amount: UInt256, - protectedTransferCall: fun (): EVM.ResultDecoded + protectedTransferCall: fun (): EVM.Result ): @{FungibleToken.Vault} { let evmAddress = self.getTargetEVMAddress()! @@ -147,7 +147,7 @@ access(all) contract FlowEVMBridgeHandlers { // After state confirmation, mint the tokens and return let minter = self.borrowMinter() - ?? panic("Cannot bridge - Minter not set in \(self.getType().identifier)") + ?? panic("Cannot bridge - Minter not set in ".concat(self.getType().identifier)) let minted <- minter.mint(amount: ufixAmount) return <-minted } @@ -170,7 +170,7 @@ access(all) contract FlowEVMBridgeHandlers { access(FlowEVMBridgeHandlerInterfaces.Admin) fun setMinter(_ minter: @{FlowEVMBridgeHandlerInterfaces.TokenMinter}) { pre { - self.minter == nil: "Minter has already been set in \(self.getType().identifier)" + self.minter == nil: "Minter has already been set in ".concat(self.getType().identifier) } self.minter <-! minter } @@ -179,7 +179,7 @@ access(all) contract FlowEVMBridgeHandlers { access(FlowEVMBridgeHandlerInterfaces.Admin) fun enableBridging() { pre { - self.minter != nil: "Cannot enable \(self.getType().identifier) without a minter" + self.minter != nil: "Cannot enable ".concat(self.getType().identifier).concat(" without a minter") } self.enabled = true } @@ -262,13 +262,12 @@ access(all) contract FlowEVMBridgeHandlers { let preBalance = FlowEVMBridgeUtils.balanceOf(owner: coa.address(), evmContractAddress: wflowAddress) // Wrap the deposited FLOW as WFLOW, giving the bridge COA the necessary WFLOW to transfer - let wrapResult = FlowEVMBridgeUtils.callWithSigAndArgs( + let wrapResult = FlowEVMBridgeUtils.call( signature: "deposit()", targetEVMAddress: wflowAddress, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: balance, - resultTypes: nil + value: balance ) assert(wrapResult.status == EVM.Status.successful, message: "Failed to wrap FLOW as WFLOW") @@ -277,12 +276,16 @@ access(all) contract FlowEVMBridgeHandlers { // Cover underflow assert( postBalance > preBalance, - message: "Escrowed WFLOW balance did not increment after wrapping FLOW - pre: \(preBalance.toString()) | post: \(postBalance.toString())" + message: "Escrowed WFLOW balance did not increment after wrapping FLOW - pre: " + .concat(preBalance.toString()).concat(" | post: ").concat(postBalance.toString()) ) // Confirm bridge COA's WFLOW balance has incremented by the expected amount assert( postBalance - preBalance == uintAmount, - message: "Escrowed WFLOW balance after wrapping does not match requested amount - expected: \(preBalance + uintAmount).toString()) | actual: \(postBalance - preBalance).toString())" + message: "Escrowed WFLOW balance after wrapping does not match requested amount - expected: " + .concat((preBalance + uintAmount).toString()) + .concat(" | actual: ") + .concat((postBalance - preBalance).toString()) ) // Transfer WFLOW to recipient @@ -304,7 +307,7 @@ access(all) contract FlowEVMBridgeHandlers { owner: EVM.EVMAddress, type: Type, amount: UInt256, - protectedTransferCall: fun (): EVM.ResultDecoded + protectedTransferCall: fun (): EVM.Result ): @{FungibleToken.Vault} { let wflowAddress = self.getTargetEVMAddress()! @@ -315,7 +318,8 @@ access(all) contract FlowEVMBridgeHandlers { ) assert( ufixAmount > 0.0, - message: "Requested UInt256 amount \(amount.toString()) converted to 0.0 - try bridging a larger amount to avoid UFix64 precision loss during conversion" + message: "Requested UInt256 amount ".concat(amount.toString()).concat(" converted to 0.0 ") + .concat(" - try bridging a larger amount to avoid UFix64 precision loss during conversion") ) // Transfers WFLOW to bridge COA as escrow @@ -331,13 +335,12 @@ access(all) contract FlowEVMBridgeHandlers { let preBalance = coa.balance().attoflow // Unwrap the transferred WFLOW to FLOW, giving the bridge COA the necessary FLOW to withdraw from EVM - let unwrapResult = FlowEVMBridgeUtils.callWithSigAndArgs( + let unwrapResult = FlowEVMBridgeUtils.call( signature: "withdraw(uint256)", targetEVMAddress: wflowAddress, args: [amount], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert(unwrapResult.status == EVM.Status.successful, message: "Failed to unwrap WFLOW as FLOW") @@ -346,29 +349,34 @@ access(all) contract FlowEVMBridgeHandlers { // Cover underflow assert( postBalance > preBalance, - message: "Escrowed FLOW Balance did not increment after unwrapping WFLOW - pre: \(preBalance.toString()) | post: \(postBalance.toString())" + message: "Escrowed FLOW Balance did not increment after unwrapping WFLOW - pre: ".concat(preBalance.toString()) + .concat(" | post: ").concat(postBalance.toString()) ) // Confirm bridge COA's FLOW balance has incremented by the expected amount assert( UInt256(postBalance - preBalance) == amount, - message: "Escrowed WFLOW balance after unwrapping does not match requested amount - expected: \(UInt256(preBalance) + amount).toString()) | actual: \(postBalance - preBalance).toString())" + message: "Escrowed WFLOW balance after unwrapping does not match requested amount - expected: " + .concat((UInt256(preBalance) + amount).toString()) + .concat(" | actual: ") + .concat((postBalance - preBalance).toString()) ) - // Withdraw escrowed FLOW from bridge COA. - // EVM.Balance takes a UInt (64-bit on all supported platforms). `UInt(amount)` truncates silently if - // `amount > UInt.max`. The assert immediately below catches any truncation: if truncation occurred, - // `UInt256(withdrawBalance.attoflow) != amount` and the transaction reverts. In practice this cannot - // trigger: total FLOW supply is ~1.25B × 10^18 attoflow ≈ 1.25e27, far below UInt.max (~1.8e19 × 1e9 - // = 1.8e28 for 64-bit). No valid WFLOW bridge request can produce an amount large enough to truncate. + // Withdraw escrowed FLOW from bridge COA let withdrawBalance = EVM.Balance(attoflow: UInt(amount)) assert( UInt256(withdrawBalance.attoflow) == amount, - message: "Requested balance failed to convert to attoflow - expected: \(amount.toString()) | actual: \(withdrawBalance.attoflow.toString())" + message: "Requested balance failed to convert to attoflow - expected: " + .concat(amount.toString()) + .concat(" | actual: ") + .concat(withdrawBalance.attoflow.toString()) ) let flowVault <- coa.withdraw(balance: withdrawBalance) assert( flowVault.balance == ufixAmount, - message: "Resulting FLOW Vault balance does not match requested amount - expected: \(ufixAmount.toString()) | actual: \(flowVault.balance.toString())" + message: "Resulting FLOW Vault balance does not match requested amount - expected: " + .concat(ufixAmount.toString()) + .concat(" | actual: ") + .concat(flowVault.balance.toString()) ) return <-flowVault } @@ -380,13 +388,15 @@ access(all) contract FlowEVMBridgeHandlers { /// Sets the target type for the handler access(FlowEVMBridgeHandlerInterfaces.Admin) fun setTargetType(_ type: Type) { - panic("WFLOWTokenHandler has targetType set to \(self.targetType.identifier) at initialization") + panic("WFLOWTokenHandler has targetType set to " + .concat(self.targetType.identifier).concat(" at initialization")) } /// Sets the target EVM address for the handler access(FlowEVMBridgeHandlerInterfaces.Admin) fun setTargetEVMAddress(_ address: EVM.EVMAddress) { - panic("WFLOWTokenHandler has EVMAddress set to \(self.targetEVMAddress.toString()) at initialization") + panic("WFLOWTokenHandler has EVMAddress set to " + .concat(self.targetEVMAddress.toString()).concat(" at initialization")) } /// Sets the target type for the handler diff --git a/cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc b/cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc index ca32e8ec..361f3163 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc @@ -1,14 +1,14 @@ -import "FungibleToken" -import "NonFungibleToken" -import "MetadataViews" -import "ViewResolver" -import "FlowToken" +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 +import MetadataViews from 0x1d7e57aa55817448 +import ViewResolver from 0x1d7e57aa55817448 +import FlowToken from 0x1654653399040a61 -import "EVM" +import EVM from 0xe467b9dd11fa00df -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "CrossVMNFT" +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 +import CrossVMNFT from 0x1e4aa0b87d10b141 /// This escrow contract handles the locking of assets that are bridged from Flow to EVM and retrieval of locked /// assets in escrow when they are bridged back to Flow. diff --git a/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc b/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc index fc1ee851..bbbd6c09 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc @@ -1,12 +1,12 @@ -import "MetadataViews" -import "FungibleTokenMetadataViews" -import "FungibleToken" -import "NonFungibleToken" - -import "ICrossVMAsset" -import "CrossVMToken" -import "CrossVMNFT" -import "FlowEVMBridgeUtils" +import MetadataViews from 0x1d7e57aa55817448 +import FungibleTokenMetadataViews from 0xf233dcee88fe0abe +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 + +import ICrossVMAsset from 0x1e4aa0b87d10b141 +import CrossVMToken from 0x1e4aa0b87d10b141 +import CrossVMNFT from 0x1e4aa0b87d10b141 +import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 /// This contract serves as a metadata resolver for shared views on NFTs and FungibleTokens bridged from EVM to Cadence. /// Upon bridging to Cadence, these tokens must have certain basic metadata views that cannot be retrieved at the time diff --git a/cadence/contracts/bridge/FlowEVMBridgeTemplates.cdc b/cadence/contracts/bridge/FlowEVMBridgeTemplates.cdc index 0ec78fcc..a78d57dd 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeTemplates.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeTemplates.cdc @@ -1,9 +1,9 @@ -import "FungibleToken" -import "NonFungibleToken" +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 -import "EVM" +import EVM from 0xe467b9dd11fa00df -import "FlowEVMBridgeUtils" +import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 /// This contract serves Cadence code from chunked templates, replacing the contract name with the name derived from /// given arguments - either Cadence Type or EVM contract address. diff --git a/cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc b/cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc index 6b91651b..7e0a5e2b 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc @@ -1,16 +1,16 @@ -import "Burner" -import "FungibleToken" -import "NonFungibleToken" -import "MetadataViews" -import "ViewResolver" -import "FlowToken" - -import "EVM" - -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "CrossVMToken" +import Burner from 0xf233dcee88fe0abe +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 +import MetadataViews from 0x1d7e57aa55817448 +import ViewResolver from 0x1d7e57aa55817448 +import FlowToken from 0x1654653399040a61 + +import EVM from 0xe467b9dd11fa00df + +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 +import CrossVMToken from 0x1e4aa0b87d10b141 /// This escrow contract handles the locking of fungible tokens that are bridged from Cadence to EVM and retrieval of /// locked assets in escrow when they are bridged back to Cadence. diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index b5cf981a..571b860b 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -1,68 +1,21 @@ -import "NonFungibleToken" -import "FungibleToken" -import "MetadataViews" -import "CrossVMMetadataViews" -import "FungibleTokenMetadataViews" -import "ViewResolver" -import "FlowToken" -import "FlowStorageFees" - -import "EVM" - -import "SerializeMetadata" -import "FlowEVMBridgeConfig" -import "CrossVMNFT" -import "IBridgePermissions" +import NonFungibleToken from 0x1d7e57aa55817448 +import FungibleToken from 0xf233dcee88fe0abe +import MetadataViews from 0x1d7e57aa55817448 +import CrossVMMetadataViews from 0x1d7e57aa55817448 +import FungibleTokenMetadataViews from 0xf233dcee88fe0abe +import ViewResolver from 0x1d7e57aa55817448 +import FlowToken from 0x1654653399040a61 +import FlowStorageFees from 0xe467b9dd11fa00df + +import EVM from 0xe467b9dd11fa00df + +import SerializeMetadata from 0x1e4aa0b87d10b141 +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import CrossVMNFT from 0x1e4aa0b87d10b141 +import IBridgePermissions from 0x1e4aa0b87d10b141 /// This contract serves as a source of utility methods leveraged by FlowEVMBridge contracts - -/*************************************************************************************** - Clarification of Flow EVM Bridge Security Model - - The bridge operates under a "trust-but-verify" model for EVM contracts: - - Trust Assumptions - - ERC20/ERC721 contracts correctly implement their respective standards. - - `balanceOf()`, `ownerOf()`, and similar view functions return accurate state. - - `transfer()`, `transferFrom()`, and similar mutating functions perform real state changes. - - Emitted events correspond to actual state transitions. - - Security Boundaries - The bridge provides the following security guarantees: - - 1. Type Isolation: Each bridged ERC20/ERC721 maps to a unique Cadence type - (e.g., `EVMVMBridgedToken_0x{ADDRESS}.Vault`). Cadence's type system ensures - complete isolation between different token types. - - 2. Cross-Asset Protection: A vulnerability or malicious behavior in one bridged - asset CANNOT affect any other bridged asset. Each type has independent accounting. - - 3. Protocol Asset Protection: Core protocol assets (FlowToken, etc.) are not - exposed to risks from user-deployed EVM contracts. - - Flow EVM Bridge design - Security Consideration - - The bridge CANNOT protect against: - - - Malicious ERC20/ERC721 contracts that return fabricated data from view functions - or fail to perform real state changes. Such contracts can cause accounting desync - for their own token type, but cannot affect other assets. - - - Token developer malfeasance ("rug pulls"). A developer who controls a token - contract can harm holders of that specific token through various means, with or - without the bridge. - - - The bridge's role is to faithfully execute cross-VM transfers for well-behaved - contracts, not to enforce correct behavior of arbitrary EVM code. - - User Responsibility - - Users interacting with bridged assets should: - - Verify the legitimacy of ERC20/ERC721 contracts before bridging. - - Understand that the bridge cannot guarantee the behavior of arbitrary EVM contracts. -***************************************************************************************/ - +// access(all) contract FlowEVMBridgeUtils { @@ -172,9 +125,9 @@ contract FlowEVMBridgeUtils { access(all) view fun typeAllowsBridging(_ type: Type): Bool { let contractAddress = self.getContractAddress(fromType: type) - ?? panic("Could not construct contract address from type identifier: \(type.identifier)") + ?? panic("Could not construct contract address from type identifier: ".concat(type.identifier)) let contractName = self.getContractName(fromType: type) - ?? panic("Could not construct contract name from type identifier: \(type.identifier)") + ?? panic("Could not construct contract name from type identifier: ".concat(type.identifier)) if let bridgePermissions = getAccount(contractAddress).contracts.borrow<&{IBridgePermissions}>(name: contractName) { return bridgePermissions.allowsBridging() } @@ -189,20 +142,20 @@ contract FlowEVMBridgeUtils { /// access(all) fun evmAddressAllowsBridging(_ address: EVM.EVMAddress): Bool { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "allowsBridging()", targetEVMAddress: address, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) // Contract doesn't support the method - proceed permissionlessly if callResult.status != EVM.Status.successful { return true } // Contract is IBridgePermissions - return the result - return (callResult.results.length == 1 && callResult.results[0] as! Bool) == true ? true : false + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) as! [AnyStruct] + return (decodedResult.length == 1 && decodedResult[0] as! Bool) == true ? true : false } /// Identifies if an asset is Cadence- or EVM-native, defined by whether a bridge contract defines it or not @@ -214,7 +167,7 @@ contract FlowEVMBridgeUtils { access(all) view fun isCadenceNative(type: Type): Bool { let definingAddress = self.getContractAddress(fromType: type) - ?? panic("Could not construct address from type identifier: \(type.identifier)") + ?? panic("Could not construct address from type identifier: ".concat(type.identifier)) return definingAddress != self.account.address } @@ -230,7 +183,7 @@ contract FlowEVMBridgeUtils { access(all) view fun isBridgeDefined(type: Type): Bool { let definingAddress = self.getContractAddress(fromType: type) - ?? panic("Could not construct address from type identifier: \(type.identifier)") + ?? panic("Could not construct address from type identifier: ".concat(type.identifier)) return definingAddress == self.account.address } @@ -256,19 +209,19 @@ contract FlowEVMBridgeUtils { access(all) fun isEVMContractBridgeOwned(evmContractAddress: EVM.EVMAddress): Bool { // Ask the bridge factory if the given contract address was deployed by the bridge - let callResult = self.dryCallWithSigAndArgs( - signature: "isBridgeDeployed(address)", - targetEVMAddress: self.bridgeFactoryEVMAddress, - args: [evmContractAddress], - gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] - ) + let callResult = self.dryCall( + signature: "isBridgeDeployed(address)", + targetEVMAddress: self.bridgeFactoryEVMAddress, + args: [evmContractAddress], + gasLimit: FlowEVMBridgeConfig.gasLimit, + value: 0.0 + ) assert(callResult.status == EVM.Status.successful, message: "Call to bridge factory failed") - assert(callResult.results.length == 1, message: "Invalid response length") + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) + assert(decodedResult.length == 1, message: "Invalid response length") - return callResult.results[0] as! Bool + return decodedResult[0] as! Bool } /// Identifies if an asset is ERC721. Reverts on EVM call failure. @@ -279,19 +232,19 @@ contract FlowEVMBridgeUtils { /// access(all) fun isERC721(evmContractAddress: EVM.EVMAddress): Bool { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "isERC721(address)", targetEVMAddress: self.bridgeFactoryEVMAddress, args: [evmContractAddress], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(callResult.status == EVM.Status.successful, message: "Call to bridge factory failed") - assert(callResult.results.length == 1, message: "Invalid response length") + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) + assert(decodedResult.length == 1, message: "Invalid response length") - return callResult.results[0] as! Bool + return decodedResult[0] as! Bool } /// Identifies if an asset is ERC20 as far as is possible without true EVM type introspection. Reverts on EVM call @@ -303,19 +256,19 @@ contract FlowEVMBridgeUtils { /// access(all) fun isERC20(evmContractAddress: EVM.EVMAddress): Bool { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "isERC20(address)", targetEVMAddress: self.bridgeFactoryEVMAddress, args: [evmContractAddress], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(callResult.status == EVM.Status.successful, message: "Call to bridge factory failed") - assert(callResult.results.length == 1, message: "Invalid response length") + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) + assert(decodedResult.length == 1, message: "Invalid response length") - return callResult.results[0] as! Bool + return decodedResult[0] as! Bool } /// Returns whether the contract address is either an ERC721 or ERC20 exclusively. Reverts on EVM call failure. @@ -326,16 +279,16 @@ contract FlowEVMBridgeUtils { /// access(all) fun isValidEVMAsset(evmContractAddress: EVM.EVMAddress): Bool { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "isValidAsset(address)", targetEVMAddress: self.bridgeFactoryEVMAddress, args: [evmContractAddress], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) - assert(callResult.results.length == 1, message: "Invalid response length") - return callResult.results[0] as! Bool + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) + assert(decodedResult.length == 1, message: "Invalid response length") + return decodedResult[0] as! Bool } /// Returns whether the given type is either an NFT or FT exclusively @@ -381,10 +334,10 @@ contract FlowEVMBridgeUtils { // Retrieve the Cadence type's defining contract name, address, & its identifier var name = self.getContractName(fromType: forAssetType) - ?? panic("Could not contract name from type: \(forAssetType.identifier)") + ?? panic("Could not contract name from type: ".concat(forAssetType.identifier)) let identifier = forAssetType.identifier let cadenceAddress = self.getContractAddress(fromType: forAssetType) - ?? panic("Could not derive contract address for token type: \(identifier)") + ?? panic("Could not derive contract address for token type: ".concat(identifier)) // Initialize asset symbol which will be assigned later // based on presence of asset-defined metadata var symbol: String? = nil @@ -411,7 +364,7 @@ contract FlowEVMBridgeUtils { ) as! MetadataViews.NFTCollectionDisplay? { name = collectionDisplay.name let serializedDisplay = SerializeMetadata.serializeFromDisplays(nftDisplay: nil, collectionDisplay: collectionDisplay)! - contractURI = "data:application/json;utf8,{\(serializedDisplay)}" + contractURI = "data:application/json;utf8,{".concat(serializedDisplay).concat("}") } if symbol == nil { symbol = SerializeMetadata.deriveSymbol(fromString: name) @@ -427,11 +380,7 @@ contract FlowEVMBridgeUtils { } if contractURI.length == 0 && ftDisplay != nil { let serializedDisplay = SerializeMetadata.serializeFTDisplay(ftDisplay!) - contractURI = "data:application/json;utf8,{\(serializedDisplay)}" - } - // Derive a symbol from the name if no metadata view provided one - if symbol == nil { - symbol = SerializeMetadata.deriveSymbol(fromString: name) + contractURI = "data:application/json;utf8,{".concat(serializedDisplay).concat("}") } } } @@ -475,7 +424,7 @@ contract FlowEVMBridgeUtils { let isERC20 = self.isERC20(evmContractAddress: evmContractAddress) assert( isERC20, - message: "Contract \(evmContractAddress.toString())defines an asset that is not currently supported by the bridge" + message: "Contract ".concat(evmContractAddress.toString()).concat("defines an asset that is not currently supported by the bridge") ) cadenceContractName = self.deriveBridgedTokenContractName(from: evmContractAddress) decimals = self.getTokenDecimals(evmContractAddress: evmContractAddress) @@ -526,19 +475,19 @@ contract FlowEVMBridgeUtils { /// access(all) fun getName(evmContractAddress: EVM.EVMAddress): String { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "name()", targetEVMAddress: evmContractAddress, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(callResult.status == EVM.Status.successful, message: "Call for EVM asset name failed") - assert(callResult.results.length == 1, message: "Invalid response length") + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) as! [AnyStruct] + assert(decodedResult.length == 1, message: "Invalid response length") - return callResult.results[0] as! String + return decodedResult[0] as! String } /// Retrieves the NFT/FT symbol from the given EVM contract address - applies for both ERC20 & ERC721 @@ -550,17 +499,17 @@ contract FlowEVMBridgeUtils { /// access(all) fun getSymbol(evmContractAddress: EVM.EVMAddress): String { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "symbol()", targetEVMAddress: evmContractAddress, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(callResult.status == EVM.Status.successful, message: "Call for EVM asset symbol failed") - assert(callResult.results.length == 1, message: "Invalid response length") - return callResult.results[0] as! String + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) as! [AnyStruct] + assert(decodedResult.length == 1, message: "Invalid response length") + return decodedResult[0] as! String } /// Retrieves the tokenURI for the given NFT ID from the given EVM contract address. Reverts on EVM call failure. @@ -573,19 +522,19 @@ contract FlowEVMBridgeUtils { /// access(all) fun getTokenURI(evmContractAddress: EVM.EVMAddress, id: UInt256): String { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "tokenURI(uint256)", targetEVMAddress: evmContractAddress, args: [id], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(callResult.status == EVM.Status.successful, message: "Call to EVM for tokenURI failed") - assert(callResult.results.length == 1, message: "Invalid response length") + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) as! [AnyStruct] + assert(decodedResult.length == 1, message: "Invalid response length") - return callResult.results[0] as! String + return decodedResult[0] as! String } /// Retrieves the contract URI from the given EVM contract address. Returns nil on EVM call failure. @@ -596,18 +545,18 @@ contract FlowEVMBridgeUtils { /// access(all) fun getContractURI(evmContractAddress: EVM.EVMAddress): String? { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "contractURI()", targetEVMAddress: evmContractAddress, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) if callResult.status != EVM.Status.successful { return nil } - return callResult.results.length == 1 ? callResult.results[0] as! String : nil + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) as! [AnyStruct] + return decodedResult.length == 1 ? decodedResult[0] as! String : nil } /// Retrieves the number of decimals for a given ERC20 contract address. Reverts on EVM call failure. @@ -618,19 +567,19 @@ contract FlowEVMBridgeUtils { /// access(all) fun getTokenDecimals(evmContractAddress: EVM.EVMAddress): UInt8 { - let callResult = self.dryCallWithSigAndArgs( - signature: "decimals()", - targetEVMAddress: evmContractAddress, - args: [], - gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] - ) + let callResult = self.dryCall( + signature: "decimals()", + targetEVMAddress: evmContractAddress, + args: [], + gasLimit: FlowEVMBridgeConfig.gasLimit, + value: 0.0 + ) assert(callResult.status == EVM.Status.successful, message: "Call for EVM asset decimals failed") - assert(callResult.results.length == 1, message: "Invalid response length") + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) as! [AnyStruct] + assert(decodedResult.length == 1, message: "Invalid response length") - return callResult.results[0] as! UInt8 + return decodedResult[0] as! UInt8 } /// Determines if the provided owner address is either the owner or approved for the NFT in the ERC721 contract @@ -670,18 +619,18 @@ contract FlowEVMBridgeUtils { /// access(all) fun ownerOf(id: UInt256, evmContractAddress: EVM.EVMAddress): EVM.EVMAddress? { - let callResult = self.dryCallWithSigAndArgs( - signature: "ownerOf(uint256)", - targetEVMAddress: evmContractAddress, - args: [id], - gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] - ) + let callResult = self.dryCall( + signature: "ownerOf(uint256)", + targetEVMAddress: evmContractAddress, + args: [id], + gasLimit: FlowEVMBridgeConfig.gasLimit, + value: 0.0 + ) if callResult.status == EVM.Status.failed { return nil } - return callResult.results.length == 1 ? callResult.results[0] as! EVM.EVMAddress : nil + let decodedCallResult = EVM.decodeABI(types: [Type()], data: callResult.data) + return decodedCallResult.length == 1 ? decodedCallResult[0] as! EVM.EVMAddress : nil } /// Returns whether the given owner is approved for the given NFT. Reverts on EVM call failure. @@ -694,17 +643,17 @@ contract FlowEVMBridgeUtils { /// access(all) fun isApproved(ofNFT: UInt256, owner: EVM.EVMAddress, evmContractAddress: EVM.EVMAddress): Bool { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "getApproved(uint256)", targetEVMAddress: evmContractAddress, args: [ofNFT], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(callResult.status == EVM.Status.successful, message: "Call to ERC721.getApproved(uint256) failed") - if callResult.results.length == 1 { - let actualApproved = callResult.results[0] as! EVM.EVMAddress + let decodedCallResult = EVM.decodeABI(types: [Type()], data: callResult.data) + if decodedCallResult.length == 1 { + let actualApproved = decodedCallResult[0] as! EVM.EVMAddress return actualApproved.equals(owner) } return false @@ -721,16 +670,18 @@ contract FlowEVMBridgeUtils { /// access(all) fun erc721Exists(erc721Address: EVM.EVMAddress, id: UInt256): Bool { - let callResult = self.dryCallWithSigAndArgs( - signature: "exists(uint256)", - targetEVMAddress: erc721Address, - args: [id], - gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] - ) - assert(callResult.results.length == 1, message: "Invalid response length") - return callResult.results[0] as! Bool + let existsResponse = EVM.decodeABI( + types: [Type()], + data: self.dryCall( + signature: "exists(uint256)", + targetEVMAddress: erc721Address, + args: [id], + gasLimit: FlowEVMBridgeConfig.gasLimit, + value: 0.0 + ).data, + ) + assert(existsResponse.length == 1, message: "Invalid response length") + return existsResponse[0] as! Bool } /// Returns the ERC20 balance of the owner at the given ERC20 contract address. Reverts on EVM call failure. @@ -743,17 +694,17 @@ contract FlowEVMBridgeUtils { /// access(all) fun balanceOf(owner: EVM.EVMAddress, evmContractAddress: EVM.EVMAddress): UInt256 { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "balanceOf(address)", targetEVMAddress: evmContractAddress, args: [owner], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(callResult.status == EVM.Status.successful, message: "Call to ERC20.balanceOf(address) failed") - assert(callResult.results.length == 1, message: "Invalid response length") - return callResult.results[0] as! UInt256 + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) as! [AnyStruct] + assert(decodedResult.length == 1, message: "Invalid response length") + return decodedResult[0] as! UInt256 } /// Determines if the owner has sufficient funds to bridge the given amount at the ERC20 contract address @@ -778,17 +729,17 @@ contract FlowEVMBridgeUtils { /// access(all) fun totalSupply(evmContractAddress: EVM.EVMAddress): UInt256 { - let callResult = self.dryCallWithSigAndArgs( + let callResult = self.dryCall( signature: "totalSupply()", targetEVMAddress: evmContractAddress, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(callResult.status == EVM.Status.successful, message: "Call to ERC20.totalSupply() failed") - assert(callResult.results.length == 1, message: "Invalid response length") - return callResult.results[0] as! UInt256 + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) as! [AnyStruct] + assert(decodedResult.length == 1, message: "Invalid response length") + return decodedResult[0] as! UInt256 } /// Converts the given amount of ERC20 tokens to the equivalent amount in FLOW tokens based on the ERC20s decimals @@ -822,23 +773,6 @@ contract FlowEVMBridgeUtils { return self.ufix64ToUInt256(value: amount, decimals: self.getTokenDecimals(evmContractAddress: erc20Address)) } - /// Converts the given ERC20 amount to the corresponding ERC20 amount after rounding down to the maximum precision - /// representable by UFix64 (8 decimal places). This ensures that the amount escrowed on the EVM side matches - /// exactly the amount that will be minted or unlocked on the Cadence side, preventing sub-UFix64-precision - /// "dust" from being permanently locked in escrow without a corresponding Cadence representation. - /// - /// @param amount: The UInt256 ERC20 amount to cast to Cadence precision - /// @param erc20Address: The EVM contract address of the ERC20 token - /// - /// @return The ERC20 UInt256 amount corresponding to the truncated Cadence UFix64 amount - /// - access(all) - fun castERC20AmountToCadencePrecision(_ amount: UInt256, erc20Address: EVM.EVMAddress): UInt256 { - let decimals = self.getTokenDecimals(evmContractAddress: erc20Address) - let ufixAmount = self.uint256ToUFix64(value: amount, decimals: decimals) - return self.ufix64ToUInt256(value: ufixAmount, decimals: decimals) - } - /// Gets the declared Cadence contract address declared by an EVM contract in conformance to the ICrossVM.sol /// contract interface. Reverts if the EVM call is unsuccessful. /// NOTE: Just because an EVM contract declares an association does not mean it it is valid! @@ -850,21 +784,21 @@ contract FlowEVMBridgeUtils { /// access(all) fun getDeclaredCadenceAddressFromCrossVM(evmContract: EVM.EVMAddress): Address? { - let cadenceAddrRes = self.dryCallWithSigAndArgs( + let cadenceAddrRes = self.dryCall( signature: "getCadenceAddress()", targetEVMAddress: evmContract, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) if cadenceAddrRes.status != EVM.Status.successful { return nil } - assert(cadenceAddrRes.results.length == 1, message: "Invalid response length") - var cadenceAddrStr = cadenceAddrRes.results[0] as! String + let decodedCadenceAddr = EVM.decodeABI(types: [Type()], data: cadenceAddrRes.data) + assert(decodedCadenceAddr.length == 1) + var cadenceAddrStr = decodedCadenceAddr[0] as! String if cadenceAddrStr[1] != "x" { - cadenceAddrStr = "0x\(cadenceAddrStr)" + cadenceAddrStr = "0x".concat(cadenceAddrStr) } return Address.fromString(cadenceAddrStr) ?? nil } @@ -881,19 +815,19 @@ contract FlowEVMBridgeUtils { /// access(all) fun getDeclaredCadenceTypeFromCrossVM(evmContract: EVM.EVMAddress): Type? { - let cadenceIdentifierRes = self.dryCallWithSigAndArgs( + let cadenceIdentifierRes = self.dryCall( signature: "getCadenceIdentifier()", targetEVMAddress: evmContract, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) if cadenceIdentifierRes.status != EVM.Status.successful { return nil } - assert(cadenceIdentifierRes.results.length == 1, message: "Invalid response length") - let cadenceIdentifier = cadenceIdentifierRes.results[0] as! String + let decodedCadenceIdentifier = EVM.decodeABI(types: [Type()], data: cadenceIdentifierRes.data) + assert(decodedCadenceIdentifier.length == 1) + let cadenceIdentifier = decodedCadenceIdentifier[0] as! String return CompositeType(cadenceIdentifier) ?? nil } @@ -908,21 +842,21 @@ contract FlowEVMBridgeUtils { access(all) fun supportsICrossVMBridgeERC721Fulfillment(evmContract: EVM.EVMAddress): Bool { let interfaceID = EVM.EVMBytes4(value: "2e608d70".decodeHex().toConstantSized<[UInt8; 4]>()!) - let supportsRes = self.dryCallWithSigAndArgs( + let supportsRes = self.dryCall( signature: "supportsInterface(bytes4)", targetEVMAddress: evmContract, args: [interfaceID], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) if supportsRes.status != EVM.Status.successful { return false } - if supportsRes.results.length != 1 { + let decodedSupports = EVM.decodeABI(types: [Type()], data: supportsRes.data) + if decodedSupports.length != 1 { return false } - return supportsRes.results[0] as! Bool + return decodedSupports[0] as! Bool } /// Returns whether the provided EVM contract conforms to ICrossVMBridgeCallable.sol contract interface. @@ -936,21 +870,21 @@ contract FlowEVMBridgeUtils { access(all) fun supportsICrossVMBridgeCallable(evmContract: EVM.EVMAddress): Bool { let interfaceID = EVM.EVMBytes4(value: "b7f9a9ec".decodeHex().toConstantSized<[UInt8; 4]>()!) - let supportsRes = self.dryCallWithSigAndArgs( + let supportsRes = self.dryCall( signature: "supportsInterface(bytes4)", targetEVMAddress: evmContract, args: [interfaceID], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) if supportsRes.status != EVM.Status.successful { return false } - if supportsRes.results.length != 1 { + let decodedSupports = EVM.decodeABI(types: [Type()], data: supportsRes.data) + if decodedSupports.length != 1 { return false } - return supportsRes.results[0] as! Bool + return decodedSupports[0] as! Bool } /// Returns whether the provided EVM contract conforms to both ICrossVMBridgeERC721Fulfillment and @@ -975,18 +909,18 @@ contract FlowEVMBridgeUtils { /// access(all) fun getVMBridgeAddressFromICrossVMBridgeCallable(evmContract: EVM.EVMAddress): EVM.EVMAddress? { - let cadenceIdentifierRes = self.dryCallWithSigAndArgs( + let cadenceIdentifierRes = self.dryCall( signature: "vmBridgeAddress()", targetEVMAddress: evmContract, args: [], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) if cadenceIdentifierRes.status != EVM.Status.successful { return nil } - return cadenceIdentifierRes.results.length == 1 ? cadenceIdentifierRes.results[0] as! EVM.EVMAddress : nil + let decodedCadenceIdentifier = EVM.decodeABI(types: [Type()], data: cadenceIdentifierRes.data) + return decodedCadenceIdentifier.length == 1 ? decodedCadenceIdentifier[0] as! EVM.EVMAddress : nil } /************************ @@ -1013,11 +947,14 @@ contract FlowEVMBridgeUtils { } assert(prefix.length > 1, message: "Invalid prefix") if let splitIdentifier = self.splitObjectIdentifier(identifier: fromType.identifier) { - let sourceContractAddress = Address.fromString("0x\(splitIdentifier[1])")! + let sourceContractAddress = Address.fromString("0x".concat(splitIdentifier[1]))! let sourceContractName = splitIdentifier[2] let resourceName = splitIdentifier[3] return StoragePath( - identifier: "\(prefix)\(self.delimiter)\(sourceContractAddress.toString())\(self.delimiter)\(sourceContractName)\(self.delimiter)\(resourceName)" + identifier: prefix.concat(self.delimiter) + .concat(sourceContractAddress.toString()).concat(self.delimiter) + .concat(sourceContractName).concat(self.delimiter) + .concat(resourceName) ) ?? nil } return nil @@ -1032,7 +969,9 @@ contract FlowEVMBridgeUtils { /// access(all) view fun deriveBridgedNFTContractName(from evmContract: EVM.EVMAddress): String { - return "\(self.contractNamePrefixes[Type<@{NonFungibleToken.NFT}>()]!["bridged"]!)\(self.delimiter)\(evmContract.toString())" + return self.contractNamePrefixes[Type<@{NonFungibleToken.NFT}>()]!["bridged"]! + .concat(self.delimiter) + .concat(evmContract.toString()) } /// Derives the Cadence contract name for a given EVM fungible token of the form @@ -1044,7 +983,9 @@ contract FlowEVMBridgeUtils { /// access(all) view fun deriveBridgedTokenContractName(from evmContract: EVM.EVMAddress): String { - return "\(self.contractNamePrefixes[Type<@{FungibleToken.Vault}>()]!["bridged"]!)\(self.delimiter)\(evmContract.toString())" + return self.contractNamePrefixes[Type<@{FungibleToken.Vault}>()]!["bridged"]! + .concat(self.delimiter) + .concat(evmContract.toString()) } /**************** @@ -1088,13 +1029,6 @@ contract FlowEVMBridgeUtils { } /// Converts a UFix64 to a UInt256 - /// - /// Note on overflow safety: `integer * integerMultiplier` where `integerMultiplier = 10^decimals` could - /// theoretically overflow UInt256 for very large `decimals` values (e.g. decimals > ~58 with a non-zero - /// integer part). In practice this is not a concern: ERC20 tokens with more than 18 decimals are outside - /// the ERC20 standard convention, and UFix64.max (~1.84e19) * 10^18 ≈ 1.84e37, well within UInt256 range. - /// The bridge sources `decimals` from on-chain ERC20 `decimals()` calls; a malicious token reporting - /// extreme decimals would only affect its own bridged representation, not other assets. // access(all) view fun ufix64ToUInt256(value: UFix64, decimals: UInt8): UInt256 { @@ -1131,12 +1065,12 @@ contract FlowEVMBridgeUtils { // Ensure the parts do not exceed the max UFix64 value before conversion assert( scaledValue <= UInt256(UFix64.max), - message: "Scaled integer value \(value.toString()) exceeds max UFix64 value" + message: "Scaled integer value ".concat(value.toString()).concat(" exceeds max UFix64 value") ) /// Check for the max value that can be converted to a UFix64 without overflowing assert( scaledValue == UInt256(UFix64.max) ? scaledFractional < 0.09551616 : true, - message: "Scaled integer value \(value.toString()) exceeds max UFix64 value" + message: "Scaled integer value ".concat(value.toString()).concat(" exceeds max UFix64 value") ) return UFix64(scaledValue) + scaledFractional @@ -1252,7 +1186,7 @@ contract FlowEVMBridgeUtils { view fun buildCompositeType(address: Address, contractName: String, resourceName: String): Type? { let addressStr = address.toString() let subtract0x = addressStr.slice(from: 2, upTo: addressStr.length) - let identifier = "A.\(subtract0x).\(contractName).\(resourceName)" + let identifier = "A".concat(".").concat(subtract0x).concat(".").concat(contractName).concat(".").concat(resourceName) return CompositeType(identifier) } @@ -1304,28 +1238,21 @@ contract FlowEVMBridgeUtils { /// Shared helper simplifying calls using the bridge account's COA /// access(account) - fun callWithSigAndArgs( + fun call( signature: String, targetEVMAddress: EVM.EVMAddress, args: [AnyStruct], gasLimit: UInt64, - value: UFix64, - resultTypes: [Type]? - ): EVM.ResultDecoded { - var valueBalance: UInt = 0 - if value > 0.0 { - let balance = EVM.Balance(attoflow: 0) - balance.setFLOW(flow: value) - valueBalance = balance.inAttoFLOW() - } - - return self.borrowCOA().callWithSigAndArgs( + value: UFix64 + ): EVM.Result { + let calldata = EVM.encodeABIWithSignature(signature, args) + let valueBalance = EVM.Balance(attoflow: 0) + valueBalance.setFLOW(flow: value) + return self.borrowCOA().call( to: targetEVMAddress, - signature: signature, - args: args, + data: calldata, gasLimit: gasLimit, - value: valueBalance, - resultTypes: resultTypes + value: valueBalance ) } @@ -1333,28 +1260,21 @@ contract FlowEVMBridgeUtils { /// call within EVM, serving solely as a mechanism for retrieving data from Flow-EVM environment. /// access(account) - fun dryCallWithSigAndArgs( + fun dryCall( signature: String, targetEVMAddress: EVM.EVMAddress, args: [AnyStruct], gasLimit: UInt64, - value: UFix64, - resultTypes: [Type]? - ): EVM.ResultDecoded { - var valueBalance: UInt = 0 - if value > 0.0 { - let balance = EVM.Balance(attoflow: 0) - balance.setFLOW(flow: value) - valueBalance = balance.inAttoFLOW() - } - - return self.borrowCOA().dryCallWithSigAndArgs( + value: UFix64 + ): EVM.Result { + let calldata = EVM.encodeABIWithSignature(signature, args) + let valueBalance = EVM.Balance(attoflow: 0) + valueBalance.setFLOW(flow: value) + return self.borrowCOA().dryCall( to: targetEVMAddress, - signature: signature, - args: args, + data: calldata, gasLimit: gasLimit, - value: valueBalance, - resultTypes: resultTypes + value: valueBalance ) } @@ -1370,13 +1290,12 @@ contract FlowEVMBridgeUtils { assert(bridgePreStatus, message: "Bridge COA does not own ERC721 requesting to be transferred") assert(!toPreStatus, message: "Recipient already owns ERC721 attempting to be transferred") - let transferResult = self.callWithSigAndArgs( + let transferResult: EVM.Result = self.call( signature: "safeTransferFrom(address,address,uint256)", targetEVMAddress: erc721Address, args: [bridgeCOAAddress, to, id], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert( transferResult.status == EVM.Status.successful, @@ -1396,13 +1315,12 @@ contract FlowEVMBridgeUtils { fun mustSafeMintERC721(erc721Address: EVM.EVMAddress, to: EVM.EVMAddress, id: UInt256, uri: String) { let bridgeCOAAddress = self.getBridgeCOAEVMAddress() - let mintResult = self.callWithSigAndArgs( + let mintResult: EVM.Result = self.call( signature: "safeMint(address,uint256,string)", targetEVMAddress: erc721Address, args: [to, id, uri], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert(mintResult.status == EVM.Status.successful, message: "Mint to bridge recipient failed") @@ -1415,13 +1333,12 @@ contract FlowEVMBridgeUtils { /// access(account) fun mustFulfillNFTToEVM(erc721Address: EVM.EVMAddress, to: EVM.EVMAddress, id: UInt256, maybeBytes: EVM.EVMBytes?) { - let fulfillResult = self.callWithSigAndArgs( + let fulfillResult = self.call( signature: "fulfillToEVM(address,uint256,bytes)", targetEVMAddress: erc721Address, args: [to, id, maybeBytes ?? EVM.EVMBytes(value: [])], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert( fulfillResult.status == EVM.Status.successful, @@ -1440,13 +1357,12 @@ contract FlowEVMBridgeUtils { fun mustUpdateTokenURI(erc721Address: EVM.EVMAddress, id: UInt256, uri: String) { let bridgeCOAAddress = self.getBridgeCOAEVMAddress() - let updateResult = self.callWithSigAndArgs( + let updateResult: EVM.Result = self.call( signature: "updateTokenURI(uint256,string)", targetEVMAddress: erc721Address, args: [id, uri], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert(updateResult.status == EVM.Status.successful, message: "URI update failed") } @@ -1460,7 +1376,7 @@ contract FlowEVMBridgeUtils { owner: EVM.EVMAddress, id: UInt256, erc721Address: EVM.EVMAddress, - protectedTransferCall: fun (EVM.EVMAddress): EVM.ResultDecoded + protectedTransferCall: fun (EVM.EVMAddress): EVM.Result ) { // Ensure the named owner is authorized to act on the NFT let isAuthorized = self.isOwnerOrApproved(ofNFT: id, owner: owner, evmContractAddress: erc721Address) @@ -1492,13 +1408,12 @@ contract FlowEVMBridgeUtils { ) let bridgeCOA = self.getBridgeCOAEVMAddress() - let unwrapResult = self.callWithSigAndArgs( + let unwrapResult: EVM.Result = self.call( signature: "withdrawTo(address,uint256[])", targetEVMAddress: erc721WrapperAddress, args: [bridgeCOA, [id]], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert( unwrapResult.status == EVM.Status.successful, @@ -1517,13 +1432,12 @@ contract FlowEVMBridgeUtils { fun mustMintERC20(to: EVM.EVMAddress, amount: UInt256, erc20Address: EVM.EVMAddress) { let toPreBalance = self.balanceOf(owner: to, evmContractAddress: erc20Address) // Mint tokens to the recipient - let mintResult = self.callWithSigAndArgs( + let mintResult: EVM.Result = self.call( signature: "mint(address,uint256)", targetEVMAddress: erc20Address, args: [to, amount], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert(mintResult.status == EVM.Status.successful, message: "Mint to bridge ERC20 contract failed") // Ensure bridge to recipient was succcessful @@ -1548,13 +1462,12 @@ contract FlowEVMBridgeUtils { ) // Transfer tokens to the recipient - let transferResult = self.callWithSigAndArgs( + let transferResult: EVM.Result = self.call( signature: "transfer(address,uint256)", targetEVMAddress: erc20Address, args: [to, amount], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert(transferResult.status == EVM.Status.successful, message: "transfer call to ERC20 contract failed") @@ -1583,7 +1496,7 @@ contract FlowEVMBridgeUtils { owner: EVM.EVMAddress, amount: UInt256, erc20Address: EVM.EVMAddress, - protectedTransferCall: fun (): EVM.ResultDecoded + protectedTransferCall: fun (): EVM.Result ) { // Ensure the caller is has sufficient balance to bridge the requested amount let hasSufficientBalance = self.hasSufficientBalance( @@ -1611,11 +1524,7 @@ contract FlowEVMBridgeUtils { evmContractAddress: erc20Address ) - // Confirm the expected amount moved from owner to bridge escrow. These post-state assertions are the - // primary security guarantee for ERC20 escrow — they catch any accounting discrepancy regardless of - // cause (reentrant callbacks, fee-on-transfer tokens, etc.). The pre-balance snapshot above is not a - // TOCTOU risk because all EVM calls within a single Cadence transaction execute within the same EVM - // block, so no interleaving can occur between the snapshot and the transfer. + // Confirm the transfer of the expected was successful in both sending owner and recipient escrow assert(ownerPostBalance == ownerPreBalance - amount, message: "Transfer to owner failed") assert(bridgePostBalance == bridgePreBalance + amount, message: "Transfer to bridge escrow failed") } @@ -1625,13 +1534,12 @@ contract FlowEVMBridgeUtils { /// access(account) fun mustBurnERC721(erc721Address: EVM.EVMAddress, id: UInt256) { - let burnResult = FlowEVMBridgeUtils.callWithSigAndArgs( + let burnResult = FlowEVMBridgeUtils.call( signature: "burn(uint256)", targetEVMAddress: erc721Address, args: [id], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ) assert(burnResult.status == EVM.Status.successful, message: "0x\(erc721Address.toString()).burn(\(id)) failed with error code \(burnResult.errorCode) and message: \(burnResult.errorMessage)") @@ -1649,17 +1557,17 @@ contract FlowEVMBridgeUtils { isERC721: Bool ): EVM.EVMAddress { let deployerTag = isERC721 ? "ERC721" : "ERC20" - let deployResult = self.callWithSigAndArgs( + let deployResult: EVM.Result = self.call( signature: "deploy(string,string,string,string,string,string)", targetEVMAddress: self.bridgeFactoryEVMAddress, args: [deployerTag, name, symbol, cadenceAddress.toString(), flowIdentifier, contractURI], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: [Type()] + value: 0.0 ) assert(deployResult.status == EVM.Status.successful, message: "EVM Token contract deployment failed") - assert(deployResult.results.length == 1, message: "Invalid response length") - return deployResult.results[0] as! EVM.EVMAddress + let decodedResult: [AnyStruct] = EVM.decodeABI(types: [Type()], data: deployResult.data) + assert(decodedResult.length == 1, message: "Invalid response length") + return decodedResult[0] as! EVM.EVMAddress } /// Calls `setSymbol(string)` on the EVM contract as exposed on FlowEVMBridgedERC721 contracts, enabling Cadence @@ -1668,13 +1576,12 @@ contract FlowEVMBridgeUtils { /// access(account) fun tryUpdateSymbol(_ evmContractAddress: EVM.EVMAddress, symbol: String): Bool { - return self.callWithSigAndArgs( + return self.call( signature: "setSymbol(string)", targetEVMAddress: evmContractAddress, args: [symbol], gasLimit: FlowEVMBridgeConfig.gasLimit, - value: 0.0, - resultTypes: nil + value: 0.0 ).status == EVM.Status.successful } diff --git a/cadence/contracts/bridge/interfaces/CrossVMNFT.cdc b/cadence/contracts/bridge/interfaces/CrossVMNFT.cdc index 68ab131c..a83e7013 100644 --- a/cadence/contracts/bridge/interfaces/CrossVMNFT.cdc +++ b/cadence/contracts/bridge/interfaces/CrossVMNFT.cdc @@ -1,10 +1,10 @@ -import "NonFungibleToken" -import "FungibleToken" -import "MetadataViews" +import NonFungibleToken from 0x1d7e57aa55817448 +import FungibleToken from 0xf233dcee88fe0abe +import MetadataViews from 0x1d7e57aa55817448 -import "EVM" +import EVM from 0xe467b9dd11fa00df -import "ICrossVMAsset" +import ICrossVMAsset from 0x1e4aa0b87d10b141 /// Contract defining cross-VM NFT-related interfaces /// diff --git a/cadence/contracts/bridge/interfaces/CrossVMToken.cdc b/cadence/contracts/bridge/interfaces/CrossVMToken.cdc index 62b3c9ad..2405fb16 100644 --- a/cadence/contracts/bridge/interfaces/CrossVMToken.cdc +++ b/cadence/contracts/bridge/interfaces/CrossVMToken.cdc @@ -1,6 +1,6 @@ -import "FungibleToken" +import FungibleToken from 0xf233dcee88fe0abe -import "EVM" +import EVM from 0xe467b9dd11fa00df /// Contract defining cross-VM Fungible Token Vault interface /// diff --git a/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc b/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc index b29ef6b7..6c8c9dee 100644 --- a/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc +++ b/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc @@ -1,7 +1,7 @@ -import "FungibleToken" -import "NonFungibleToken" +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 -import "EVM" +import EVM from 0xe467b9dd11fa00df /// FlowEVMBridgeHandlerInterfaces /// @@ -125,7 +125,7 @@ access(all) contract FlowEVMBridgeHandlerInterfaces { access(Admin) fun disableBridging() { pre { self.isEnabled(): - "Cannot disable: \(self.getType().identifier) is already disabled" + "Cannot disable: ".concat(self.getType().identifier).concat(" is already disabled") } post { !self.isEnabled(): @@ -173,9 +173,12 @@ access(all) contract FlowEVMBridgeHandlerInterfaces { ) { pre { self.isEnabled(): - "TokenHandler \(self.getType().identifier) with uuid \(self.uuid.toString()) is not yet enabled" + "TokenHandler ".concat(self.getType().identifier).concat(" with uuid ") + .concat(self.uuid.toString()).concat(" is not yet enabled") tokens.getType() == self.getTargetType(): - "TokenHandler \(self.getType().identifier) with uuid \(self.uuid.toString()) expects \(self.getTargetType()?.identifier ?? "nil") but received \(tokens.getType().identifier)" + "TokenHandler ".concat(self.getType().identifier).concat(" with uuid ").concat(self.uuid.toString()) + .concat(" expects ").concat(self.getTargetType()?.identifier ?? "nil") + .concat(" but received ").concat(tokens.getType().identifier) tokens.balance > 0.0: "Attempting to bridge 0.0 tokens - zero amounts are unsupported" } @@ -185,12 +188,13 @@ access(all) contract FlowEVMBridgeHandlerInterfaces { owner: EVM.EVMAddress, type: Type, amount: UInt256, - protectedTransferCall: fun (): EVM.ResultDecoded + protectedTransferCall: fun (): EVM.Result ): @{FungibleToken.Vault} { pre { self.isEnabled(): - "TokenHandler \(self.getType().identifier) with uuid \(self.uuid.toString()) is not yet enabled" - amount > 0: "Attempting to bridge 0 tokens from EVM - zero amounts are unsupported" + "TokenHandler ".concat(self.getType().identifier).concat(" with uuid ") + .concat(self.uuid.toString()).concat(" is not yet enabled") + amount > UInt256(0): "Attempting to bridge 0 tokens from EVM - zero amounts are unsupported" } post { result.getType() == self.getTargetType(): diff --git a/cadence/contracts/bridge/interfaces/ICrossVM.cdc b/cadence/contracts/bridge/interfaces/ICrossVM.cdc index 73219e7d..06e45c57 100644 --- a/cadence/contracts/bridge/interfaces/ICrossVM.cdc +++ b/cadence/contracts/bridge/interfaces/ICrossVM.cdc @@ -1,4 +1,4 @@ -import "EVM" +import EVM from 0xe467b9dd11fa00df /// Contract interface denoting a cross-VM implementation, exposing methods to query EVM-associated addresses /// diff --git a/cadence/contracts/bridge/interfaces/ICrossVMAsset.cdc b/cadence/contracts/bridge/interfaces/ICrossVMAsset.cdc index fb8fa8a1..5ce81157 100644 --- a/cadence/contracts/bridge/interfaces/ICrossVMAsset.cdc +++ b/cadence/contracts/bridge/interfaces/ICrossVMAsset.cdc @@ -1,6 +1,6 @@ -import "EVM" +import EVM from 0xe467b9dd11fa00df -import "ICrossVM" +import ICrossVM from 0x1e4aa0b87d10b141 /// A simple contract interface for a Cadence contract that represents an asset bridged from Flow EVM such as an ERC20 /// or ERC721 token. diff --git a/cadence/contracts/bridge/interfaces/IEVMBridgeNFTMinter.cdc b/cadence/contracts/bridge/interfaces/IEVMBridgeNFTMinter.cdc index 93908c9a..976e47a9 100644 --- a/cadence/contracts/bridge/interfaces/IEVMBridgeNFTMinter.cdc +++ b/cadence/contracts/bridge/interfaces/IEVMBridgeNFTMinter.cdc @@ -1,4 +1,4 @@ -import "NonFungibleToken" +import NonFungibleToken from 0x1d7e57aa55817448 /// Contract interface enabling FlowEVMBridge to mint NFTs from implementing bridge contracts. /// diff --git a/cadence/contracts/bridge/interfaces/IEVMBridgeTokenMinter.cdc b/cadence/contracts/bridge/interfaces/IEVMBridgeTokenMinter.cdc index f5ce9120..2a44b568 100644 --- a/cadence/contracts/bridge/interfaces/IEVMBridgeTokenMinter.cdc +++ b/cadence/contracts/bridge/interfaces/IEVMBridgeTokenMinter.cdc @@ -1,4 +1,4 @@ -import "FungibleToken" +import FungibleToken from 0xf233dcee88fe0abe /// Contract interface enabling FlowEVMBridge to mint fungible tokens from implementing bridge contracts. /// diff --git a/cadence/contracts/bridge/interfaces/IFlowEVMNFTBridge.cdc b/cadence/contracts/bridge/interfaces/IFlowEVMNFTBridge.cdc index 054afb6a..0dbcfd04 100644 --- a/cadence/contracts/bridge/interfaces/IFlowEVMNFTBridge.cdc +++ b/cadence/contracts/bridge/interfaces/IFlowEVMNFTBridge.cdc @@ -1,10 +1,10 @@ -import "FungibleToken" -import "NonFungibleToken" +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 -import "EVM" +import EVM from 0xe467b9dd11fa00df -import "FlowEVMBridgeConfig" -import "CrossVMNFT" +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import CrossVMNFT from 0x1e4aa0b87d10b141 access(all) contract interface IFlowEVMNFTBridge { @@ -74,7 +74,8 @@ access(all) contract interface IFlowEVMNFTBridge { to: to.toString(), evmContractAddress: self.getAssociatedEVMAddress(with: token.getType())?.toString() ?? panic( - "Could not find EVM Contract address associated with provided NFT identifier=\(token.getType().identifier)" + "Could not find EVM Contract address associated with provided NFT identifier=" + .concat(token.getType().identifier) ), bridgeAddress: self.account.address ) @@ -100,7 +101,7 @@ access(all) contract interface IFlowEVMNFTBridge { type: Type, id: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (EVM.EVMAddress): EVM.ResultDecoded + protectedTransferCall: fun (EVM.EVMAddress): EVM.Result ): @{NonFungibleToken.NFT} { post { emit BridgedNFTFromEVM( diff --git a/cadence/contracts/bridge/interfaces/IFlowEVMTokenBridge.cdc b/cadence/contracts/bridge/interfaces/IFlowEVMTokenBridge.cdc index 180d6628..942eb8fe 100644 --- a/cadence/contracts/bridge/interfaces/IFlowEVMTokenBridge.cdc +++ b/cadence/contracts/bridge/interfaces/IFlowEVMTokenBridge.cdc @@ -1,7 +1,7 @@ -import "FungibleToken" -import "NonFungibleToken" +import FungibleToken from 0xf233dcee88fe0abe +import NonFungibleToken from 0x1d7e57aa55817448 -import "EVM" +import EVM from 0xe467b9dd11fa00df access(all) contract interface IFlowEVMTokenBridge { @@ -68,7 +68,8 @@ access(all) contract interface IFlowEVMTokenBridge { to: to.toString(), evmContractAddress: self.getAssociatedEVMAddress(with: vault.getType())?.toString() ?? panic( - "Could not find EVM Contract address associated with provided Token identifier=\(vault.getType().identifier)" + "Could not find EVM Contract address associated with provided Token identifier=" + .concat(vault.getType().identifier) ), bridgeAddress: self.account.address ) @@ -94,7 +95,7 @@ access(all) contract interface IFlowEVMTokenBridge { type: Type, amount: UInt256, feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}, - protectedTransferCall: fun (): EVM.ResultDecoded + protectedTransferCall: fun (): EVM.Result ): @{FungibleToken.Vault} { post { emit BridgedTokensFromEVM( diff --git a/cadence/contracts/example-assets/ExampleNFT.cdc b/cadence/contracts/example-assets/ExampleNFT.cdc index 1ae72dc9..1576dbf5 100644 --- a/cadence/contracts/example-assets/ExampleNFT.cdc +++ b/cadence/contracts/example-assets/ExampleNFT.cdc @@ -10,9 +10,9 @@ * */ -import "NonFungibleToken" -import "ViewResolver" -import "MetadataViews" +import NonFungibleToken from 0x1d7e57aa55817448 +import ViewResolver from 0x1d7e57aa55817448 +import MetadataViews from 0x1d7e57aa55817448 access(all) contract ExampleNFT: NonFungibleToken { diff --git a/cadence/contracts/example-assets/ExampleToken.cdc b/cadence/contracts/example-assets/ExampleToken.cdc index 91415bad..e3c2d16f 100644 --- a/cadence/contracts/example-assets/ExampleToken.cdc +++ b/cadence/contracts/example-assets/ExampleToken.cdc @@ -1,6 +1,6 @@ -import "FungibleToken" -import "MetadataViews" -import "FungibleTokenMetadataViews" +import FungibleToken from 0xf233dcee88fe0abe +import MetadataViews from 0x1d7e57aa55817448 +import FungibleTokenMetadataViews from 0xf233dcee88fe0abe access(all) contract ExampleToken: FungibleToken { diff --git a/cadence/contracts/handled-tokens/USDCFlow.cdc b/cadence/contracts/handled-tokens/USDCFlow.cdc index 76baa836..b0cc3e0c 100644 --- a/cadence/contracts/handled-tokens/USDCFlow.cdc +++ b/cadence/contracts/handled-tokens/USDCFlow.cdc @@ -1,27 +1,18 @@ -import "FungibleToken" -import "FungibleTokenMetadataViews" -import "MetadataViews" -import "Burner" - -import "FlowEVMBridgeHandlerInterfaces" -import "FlowEVMBridgeConfig" - -/// USDCFlow -/// -/// Defines the Cadence version of bridged Flow USDC. -/// Before the Sept 4th, 2024 Crescendo migration, users can send -/// `FiatToken` vaults to the `USDCFlow.wrapFiatToken()` function -/// and receive `USDCFlow` vaults back with the exact same balance. - -/// After the Crescendo migration, the `USDCFlow` smart contract -/// will integrate directly with the Flow VM bridge to become -/// the bridged version of Flow EVM USDC. These tokens will be backed -/// by real USDC via Flow EVM. +import FungibleToken from 0xf233dcee88fe0abe +import FungibleTokenMetadataViews from 0xf233dcee88fe0abe +import MetadataViews from 0x1d7e57aa55817448 +import Burner from 0xf233dcee88fe0abe +import ViewResolver from 0x1d7e57aa55817448 +import FlowEVMBridgeHandlerInterfaces from 0x1e4aa0b87d10b141 + +/// The `USDCFlow` smart contract is integrated directly +/// with the Flow VM bridge as the bridged version of Flow EVM USDC +/// which is itself the bridged version of official USDC from Ethereum Mainnet. /// This is not the official Circle USDC, only a bridged version /// that is still backed by official USDC on the other side of the bridge -access(all) contract USDCFlow: FungibleToken { +access(all) contract USDCFlow: FungibleToken, ViewResolver { /// Total supply of USDCFlows in existence access(all) var totalSupply: UFix64 @@ -54,20 +45,18 @@ access(all) contract USDCFlow: FungibleToken { case Type(): let media = MetadataViews.Media( file: MetadataViews.HTTPFile( - url: "https://assets.website-files.com/5f6294c0c7a8cdd643b1c820/5f6294c0c7a8cda55cb1c936_Flow_Wordmark.svg" + url: "https://uploads-ssl.webflow.com/5f734f4dbd95382f4fdfa0ea/66bfae00953c3d7bd09e7ac4_USDC-and-FLOW.svg" ), mediaType: "image/svg+xml" ) let medias = MetadataViews.Medias([media]) return FungibleTokenMetadataViews.FTDisplay( - name: "USDC (Flow)", - symbol: "USDCf", - description: "This fungible token representation of USDC is bridged from Flow EVM.", - externalURL: MetadataViews.ExternalURL("https://www.circle.com/en/usdc"), + name: "USDC.e (Flow)", + symbol: "USDC.e", + description: "This fungible token representation of Standard Bridged USDC is bridged from Flow EVM.", + externalURL: MetadataViews.ExternalURL("https://github.com/circlefin/stablecoin-evm/blob/master/doc/bridged_USDC_standard.md"), logos: medias, - socials: { - "x": MetadataViews.ExternalURL("https://x.com/circle") - } + socials: {}, ) case Type(): return FungibleTokenMetadataViews.FTVaultData( @@ -196,22 +185,6 @@ access(all) contract USDCFlow: FungibleToken { } } - /// Sends the USDCFlow Minter to the Flow/EVM bridge - /// without giving any account access to the minter - /// before it is safely in the decentralized bridge - access(all) fun sendMinterToBridge(_ bridgeAddress: Address) { - let minter <- create Minter() - // borrow a reference to the bridge's configuration admin resource from public Capability - let bridgeAdmin = getAccount(bridgeAddress).capabilities.borrow<&FlowEVMBridgeConfig.Admin>( - FlowEVMBridgeConfig.adminPublicPath - ) ?? panic("FlowEVMBridgeConfig.Admin could not be referenced from ".concat(bridgeAddress.toString())) - - // sets the USDCFlow as the minter resource for all USDCFlow bridge requests - // prior to transferring the Minter, a TokenHandler will be set for USDCFlow during the bridge's initial - // configuration, setting the stage for this minter to be sent. - bridgeAdmin.setTokenHandlerMinter(targetType: Type<@USDCFlow.Vault>(), minter: <-minter) - } - /// createEmptyVault /// /// @return The new Vault resource with a balance of zero @@ -238,4 +211,4 @@ access(all) contract USDCFlow: FungibleToken { self.account.capabilities.publish(tokenCap, at: self.ReceiverPublicPath) self.account.capabilities.publish(tokenCap, at: self.VaultPublicPath) } -} \ No newline at end of file +} diff --git a/cadence/contracts/utils/ScopedFTProviders.cdc b/cadence/contracts/utils/ScopedFTProviders.cdc index 77c76ced..a6ff495f 100644 --- a/cadence/contracts/utils/ScopedFTProviders.cdc +++ b/cadence/contracts/utils/ScopedFTProviders.cdc @@ -1,5 +1,5 @@ -import "FungibleToken" -import "StringUtils" +import FungibleToken from 0xf233dcee88fe0abe +import StringUtils from 0x1e4aa0b87d10b141 // Copied from https://github.com/green-goo-dao/flow-utils/blob/crescendo/contracts/ScopedFTProviders.cdc with minor changes // Special thanks to the Green Goo Dao contributors for creating this contract diff --git a/cadence/contracts/utils/Serialize.cdc b/cadence/contracts/utils/Serialize.cdc index 41c9892f..a70f4b8e 100644 --- a/cadence/contracts/utils/Serialize.cdc +++ b/cadence/contracts/utils/Serialize.cdc @@ -1,6 +1,6 @@ -import "ViewResolver" -import "MetadataViews" -import "NonFungibleToken" +import ViewResolver from 0x1d7e57aa55817448 +import MetadataViews from 0x1d7e57aa55817448 +import NonFungibleToken from 0x1d7e57aa55817448 /// This contract is a utility for serializing primitive types, arrays, and common metadata mapping formats to JSON /// compatible strings. Also included are interfaces enabling custom serialization for structs and resources. diff --git a/cadence/contracts/utils/SerializeMetadata.cdc b/cadence/contracts/utils/SerializeMetadata.cdc index 1ceca382..f948b582 100644 --- a/cadence/contracts/utils/SerializeMetadata.cdc +++ b/cadence/contracts/utils/SerializeMetadata.cdc @@ -1,9 +1,9 @@ -import "ViewResolver" -import "MetadataViews" -import "NonFungibleToken" -import "FungibleTokenMetadataViews" +import ViewResolver from 0x1d7e57aa55817448 +import MetadataViews from 0x1d7e57aa55817448 +import NonFungibleToken from 0x1d7e57aa55817448 +import FungibleTokenMetadataViews from 0xf233dcee88fe0abe -import "Serialize" +import Serialize from 0x1e4aa0b87d10b141 /// This contract defines methods for serializing NFT metadata as a JSON compatible string, according to the common /// OpenSea metadata format. NFTs and metadata views can be serialized by reference via contract methods. diff --git a/cadence/contracts/utils/StringUtils.cdc b/cadence/contracts/utils/StringUtils.cdc index 4af734e6..ffce9f0f 100644 --- a/cadence/contracts/utils/StringUtils.cdc +++ b/cadence/contracts/utils/StringUtils.cdc @@ -1,4 +1,4 @@ -import "ArrayUtils" +import ArrayUtils from 0x1e4aa0b87d10b141 // Copied from https://github.com/green-goo-dao/flow-utils/blob/crescendo/contracts/StringUtils.cdc // Special thanks to the Green Goo Dao contributors for creating this contract From d9ac7f5025436225dce30291f16696abb3ac0112 Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:53:09 -0400 Subject: [PATCH 2/4] chore: normalize imports to string format for cleaner upgrade diff Replace all `import ContractName from 0xADDRESS` with `import "ContractName"` to match the target branch format and reduce noise in the review PR. --- cadence/contracts/bridge/FlowEVMBridge.cdc | 54 +++++++++---------- .../bridge/FlowEVMBridgeAccessor.cdc | 12 ++--- .../contracts/bridge/FlowEVMBridgeConfig.cdc | 8 +-- .../FlowEVMBridgeCustomAssociationTypes.cdc | 8 +-- .../FlowEVMBridgeCustomAssociations.cdc | 8 +-- .../bridge/FlowEVMBridgeHandlers.cdc | 16 +++--- .../bridge/FlowEVMBridgeNFTEscrow.cdc | 18 +++---- .../bridge/FlowEVMBridgeResolver.cdc | 18 +++---- .../bridge/FlowEVMBridgeTemplates.cdc | 8 +-- .../bridge/FlowEVMBridgeTokenEscrow.cdc | 24 ++++----- .../contracts/bridge/FlowEVMBridgeUtils.cdc | 30 +++++------ .../bridge/interfaces/CrossVMNFT.cdc | 10 ++-- .../bridge/interfaces/CrossVMToken.cdc | 4 +- .../FlowEVMBridgeHandlerInterfaces.cdc | 6 +-- .../contracts/bridge/interfaces/ICrossVM.cdc | 2 +- .../bridge/interfaces/ICrossVMAsset.cdc | 4 +- .../bridge/interfaces/IEVMBridgeNFTMinter.cdc | 2 +- .../interfaces/IEVMBridgeTokenMinter.cdc | 2 +- .../bridge/interfaces/IFlowEVMNFTBridge.cdc | 10 ++-- .../bridge/interfaces/IFlowEVMTokenBridge.cdc | 6 +-- .../contracts/example-assets/ExampleNFT.cdc | 6 +-- .../contracts/example-assets/ExampleToken.cdc | 6 +-- cadence/contracts/handled-tokens/USDCFlow.cdc | 12 ++--- .../emulator/EVMBridgedNFTTemplate.cdc | 34 ++++++------ .../emulator/EVMBridgedTokenTemplate.cdc | 32 +++++------ .../mainnet/EVMBridgedNFTTemplate.cdc | 34 ++++++------ .../mainnet/EVMBridgedTokenTemplate.cdc | 32 +++++------ .../testing/EVMBridgedNFTTemplate.cdc | 34 ++++++------ .../testing/EVMBridgedTokenTemplate.cdc | 32 +++++------ .../testnet/EVMBridgedNFTTemplate.cdc | 34 ++++++------ .../testnet/EVMBridgedTokenTemplate.cdc | 32 +++++------ cadence/contracts/utils/ScopedFTProviders.cdc | 4 +- cadence/contracts/utils/Serialize.cdc | 6 +-- cadence/contracts/utils/SerializeMetadata.cdc | 10 ++-- cadence/contracts/utils/StringUtils.cdc | 2 +- 35 files changed, 280 insertions(+), 280 deletions(-) diff --git a/cadence/contracts/bridge/FlowEVMBridge.cdc b/cadence/contracts/bridge/FlowEVMBridge.cdc index 7a8b8287..859a1500 100644 --- a/cadence/contracts/bridge/FlowEVMBridge.cdc +++ b/cadence/contracts/bridge/FlowEVMBridge.cdc @@ -1,30 +1,30 @@ -import Burner from 0xf233dcee88fe0abe -import FungibleToken from 0xf233dcee88fe0abe -import FungibleTokenMetadataViews from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 -import MetadataViews from 0x1d7e57aa55817448 -import CrossVMMetadataViews from 0x1d7e57aa55817448 -import ViewResolver from 0x1d7e57aa55817448 - -import EVM from 0xe467b9dd11fa00df - -import IBridgePermissions from 0x1e4aa0b87d10b141 -import ICrossVM from 0x1e4aa0b87d10b141 -import IEVMBridgeNFTMinter from 0x1e4aa0b87d10b141 -import IEVMBridgeTokenMinter from 0x1e4aa0b87d10b141 -import IFlowEVMNFTBridge from 0x1e4aa0b87d10b141 -import IFlowEVMTokenBridge from 0x1e4aa0b87d10b141 -import CrossVMNFT from 0x1e4aa0b87d10b141 -import CrossVMToken from 0x1e4aa0b87d10b141 -import FlowEVMBridgeCustomAssociationTypes from 0x1e4aa0b87d10b141 -import FlowEVMBridgeCustomAssociations from 0x1e4aa0b87d10b141 -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import FlowEVMBridgeHandlerInterfaces from 0x1e4aa0b87d10b141 -import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 -import FlowEVMBridgeNFTEscrow from 0x1e4aa0b87d10b141 -import FlowEVMBridgeTokenEscrow from 0x1e4aa0b87d10b141 -import FlowEVMBridgeTemplates from 0x1e4aa0b87d10b141 -import SerializeMetadata from 0x1e4aa0b87d10b141 +import "Burner" +import "FungibleToken" +import "FungibleTokenMetadataViews" +import "NonFungibleToken" +import "MetadataViews" +import "CrossVMMetadataViews" +import "ViewResolver" + +import "EVM" + +import "IBridgePermissions" +import "ICrossVM" +import "IEVMBridgeNFTMinter" +import "IEVMBridgeTokenMinter" +import "IFlowEVMNFTBridge" +import "IFlowEVMTokenBridge" +import "CrossVMNFT" +import "CrossVMToken" +import "FlowEVMBridgeCustomAssociationTypes" +import "FlowEVMBridgeCustomAssociations" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeHandlerInterfaces" +import "FlowEVMBridgeUtils" +import "FlowEVMBridgeNFTEscrow" +import "FlowEVMBridgeTokenEscrow" +import "FlowEVMBridgeTemplates" +import "SerializeMetadata" /// The FlowEVMBridge contract is the main entrypoint for bridging NFT & FT assets between Flow & FlowEVM. /// diff --git a/cadence/contracts/bridge/FlowEVMBridgeAccessor.cdc b/cadence/contracts/bridge/FlowEVMBridgeAccessor.cdc index 7532bd76..e35ba424 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeAccessor.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeAccessor.cdc @@ -1,11 +1,11 @@ -import NonFungibleToken from 0x1d7e57aa55817448 -import FungibleToken from 0xf233dcee88fe0abe -import FlowToken from 0x1654653399040a61 +import "NonFungibleToken" +import "FungibleToken" +import "FlowToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import FlowEVMBridge from 0x1e4aa0b87d10b141 +import "FlowEVMBridgeConfig" +import "FlowEVMBridge" /// This contract defines a mechanism for routing bridge requests from the EVM contract to the Flow-EVM bridge contract /// diff --git a/cadence/contracts/bridge/FlowEVMBridgeConfig.cdc b/cadence/contracts/bridge/FlowEVMBridgeConfig.cdc index 01eb72c8..36116a2d 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeConfig.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeConfig.cdc @@ -1,8 +1,8 @@ -import EVM from 0xe467b9dd11fa00df -import NonFungibleToken from 0x1d7e57aa55817448 +import "EVM" +import "NonFungibleToken" -import FlowEVMBridgeHandlerInterfaces from 0x1e4aa0b87d10b141 -import FlowEVMBridgeCustomAssociations from 0x1e4aa0b87d10b141 +import "FlowEVMBridgeHandlerInterfaces" +import "FlowEVMBridgeCustomAssociations" /// This contract is used to store configuration information shared by FlowEVMBridge contracts /// diff --git a/cadence/contracts/bridge/FlowEVMBridgeCustomAssociationTypes.cdc b/cadence/contracts/bridge/FlowEVMBridgeCustomAssociationTypes.cdc index 715833f0..fae6c727 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeCustomAssociationTypes.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeCustomAssociationTypes.cdc @@ -1,7 +1,7 @@ -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 -import CrossVMMetadataViews from 0x1d7e57aa55817448 -import EVM from 0xe467b9dd11fa00df +import "FungibleToken" +import "NonFungibleToken" +import "CrossVMMetadataViews" +import "EVM" /// This contract defines types required for custom cross-VM associations as used in FlowEVMBridgeCustomAssociation /// and in EVM-native cross-VM NFTs. diff --git a/cadence/contracts/bridge/FlowEVMBridgeCustomAssociations.cdc b/cadence/contracts/bridge/FlowEVMBridgeCustomAssociations.cdc index 9f735b1b..6dea1a45 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeCustomAssociations.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeCustomAssociations.cdc @@ -1,8 +1,8 @@ -import NonFungibleToken from 0x1d7e57aa55817448 -import CrossVMMetadataViews from 0x1d7e57aa55817448 -import EVM from 0xe467b9dd11fa00df +import "NonFungibleToken" +import "CrossVMMetadataViews" +import "EVM" -import FlowEVMBridgeCustomAssociationTypes from 0x1e4aa0b87d10b141 +import "FlowEVMBridgeCustomAssociationTypes" /// The FlowEVMBridgeCustomAssociations is tasked with preserving custom associations between Cadence assets and their /// EVM implementations. These associations should be validated before `saveCustomAssociation` is called by diff --git a/cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc b/cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc index fb922546..986f8ed7 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc @@ -1,13 +1,13 @@ -import Burner from 0xf233dcee88fe0abe -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 -import FlowToken from 0x1654653399040a61 +import "Burner" +import "FungibleToken" +import "NonFungibleToken" +import "FlowToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" -import FlowEVMBridgeHandlerInterfaces from 0x1e4aa0b87d10b141 -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 +import "FlowEVMBridgeHandlerInterfaces" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" /// FlowEVMBridgeHandlers /// diff --git a/cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc b/cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc index 361f3163..ca32e8ec 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc @@ -1,14 +1,14 @@ -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 -import MetadataViews from 0x1d7e57aa55817448 -import ViewResolver from 0x1d7e57aa55817448 -import FlowToken from 0x1654653399040a61 +import "FungibleToken" +import "NonFungibleToken" +import "MetadataViews" +import "ViewResolver" +import "FlowToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 -import CrossVMNFT from 0x1e4aa0b87d10b141 +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "CrossVMNFT" /// This escrow contract handles the locking of assets that are bridged from Flow to EVM and retrieval of locked /// assets in escrow when they are bridged back to Flow. diff --git a/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc b/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc index bbbd6c09..fc1ee851 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc @@ -1,12 +1,12 @@ -import MetadataViews from 0x1d7e57aa55817448 -import FungibleTokenMetadataViews from 0xf233dcee88fe0abe -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 - -import ICrossVMAsset from 0x1e4aa0b87d10b141 -import CrossVMToken from 0x1e4aa0b87d10b141 -import CrossVMNFT from 0x1e4aa0b87d10b141 -import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 +import "MetadataViews" +import "FungibleTokenMetadataViews" +import "FungibleToken" +import "NonFungibleToken" + +import "ICrossVMAsset" +import "CrossVMToken" +import "CrossVMNFT" +import "FlowEVMBridgeUtils" /// This contract serves as a metadata resolver for shared views on NFTs and FungibleTokens bridged from EVM to Cadence. /// Upon bridging to Cadence, these tokens must have certain basic metadata views that cannot be retrieved at the time diff --git a/cadence/contracts/bridge/FlowEVMBridgeTemplates.cdc b/cadence/contracts/bridge/FlowEVMBridgeTemplates.cdc index a78d57dd..0ec78fcc 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeTemplates.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeTemplates.cdc @@ -1,9 +1,9 @@ -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 +import "FungibleToken" +import "NonFungibleToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" -import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 +import "FlowEVMBridgeUtils" /// This contract serves Cadence code from chunked templates, replacing the contract name with the name derived from /// given arguments - either Cadence Type or EVM contract address. diff --git a/cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc b/cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc index 7e0a5e2b..6b91651b 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc @@ -1,16 +1,16 @@ -import Burner from 0xf233dcee88fe0abe -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 -import MetadataViews from 0x1d7e57aa55817448 -import ViewResolver from 0x1d7e57aa55817448 -import FlowToken from 0x1654653399040a61 - -import EVM from 0xe467b9dd11fa00df - -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 -import CrossVMToken from 0x1e4aa0b87d10b141 +import "Burner" +import "FungibleToken" +import "NonFungibleToken" +import "MetadataViews" +import "ViewResolver" +import "FlowToken" + +import "EVM" + +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "CrossVMToken" /// This escrow contract handles the locking of fungible tokens that are bridged from Cadence to EVM and retrieval of /// locked assets in escrow when they are bridged back to Cadence. diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 571b860b..43981f5e 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -1,18 +1,18 @@ -import NonFungibleToken from 0x1d7e57aa55817448 -import FungibleToken from 0xf233dcee88fe0abe -import MetadataViews from 0x1d7e57aa55817448 -import CrossVMMetadataViews from 0x1d7e57aa55817448 -import FungibleTokenMetadataViews from 0xf233dcee88fe0abe -import ViewResolver from 0x1d7e57aa55817448 -import FlowToken from 0x1654653399040a61 -import FlowStorageFees from 0xe467b9dd11fa00df - -import EVM from 0xe467b9dd11fa00df - -import SerializeMetadata from 0x1e4aa0b87d10b141 -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import CrossVMNFT from 0x1e4aa0b87d10b141 -import IBridgePermissions from 0x1e4aa0b87d10b141 +import "NonFungibleToken" +import "FungibleToken" +import "MetadataViews" +import "CrossVMMetadataViews" +import "FungibleTokenMetadataViews" +import "ViewResolver" +import "FlowToken" +import "FlowStorageFees" + +import "EVM" + +import "SerializeMetadata" +import "FlowEVMBridgeConfig" +import "CrossVMNFT" +import "IBridgePermissions" /// This contract serves as a source of utility methods leveraged by FlowEVMBridge contracts // diff --git a/cadence/contracts/bridge/interfaces/CrossVMNFT.cdc b/cadence/contracts/bridge/interfaces/CrossVMNFT.cdc index a83e7013..68ab131c 100644 --- a/cadence/contracts/bridge/interfaces/CrossVMNFT.cdc +++ b/cadence/contracts/bridge/interfaces/CrossVMNFT.cdc @@ -1,10 +1,10 @@ -import NonFungibleToken from 0x1d7e57aa55817448 -import FungibleToken from 0xf233dcee88fe0abe -import MetadataViews from 0x1d7e57aa55817448 +import "NonFungibleToken" +import "FungibleToken" +import "MetadataViews" -import EVM from 0xe467b9dd11fa00df +import "EVM" -import ICrossVMAsset from 0x1e4aa0b87d10b141 +import "ICrossVMAsset" /// Contract defining cross-VM NFT-related interfaces /// diff --git a/cadence/contracts/bridge/interfaces/CrossVMToken.cdc b/cadence/contracts/bridge/interfaces/CrossVMToken.cdc index 2405fb16..62b3c9ad 100644 --- a/cadence/contracts/bridge/interfaces/CrossVMToken.cdc +++ b/cadence/contracts/bridge/interfaces/CrossVMToken.cdc @@ -1,6 +1,6 @@ -import FungibleToken from 0xf233dcee88fe0abe +import "FungibleToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" /// Contract defining cross-VM Fungible Token Vault interface /// diff --git a/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc b/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc index 6c8c9dee..e22869d4 100644 --- a/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc +++ b/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc @@ -1,7 +1,7 @@ -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 +import "FungibleToken" +import "NonFungibleToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" /// FlowEVMBridgeHandlerInterfaces /// diff --git a/cadence/contracts/bridge/interfaces/ICrossVM.cdc b/cadence/contracts/bridge/interfaces/ICrossVM.cdc index 06e45c57..73219e7d 100644 --- a/cadence/contracts/bridge/interfaces/ICrossVM.cdc +++ b/cadence/contracts/bridge/interfaces/ICrossVM.cdc @@ -1,4 +1,4 @@ -import EVM from 0xe467b9dd11fa00df +import "EVM" /// Contract interface denoting a cross-VM implementation, exposing methods to query EVM-associated addresses /// diff --git a/cadence/contracts/bridge/interfaces/ICrossVMAsset.cdc b/cadence/contracts/bridge/interfaces/ICrossVMAsset.cdc index 5ce81157..fb8fa8a1 100644 --- a/cadence/contracts/bridge/interfaces/ICrossVMAsset.cdc +++ b/cadence/contracts/bridge/interfaces/ICrossVMAsset.cdc @@ -1,6 +1,6 @@ -import EVM from 0xe467b9dd11fa00df +import "EVM" -import ICrossVM from 0x1e4aa0b87d10b141 +import "ICrossVM" /// A simple contract interface for a Cadence contract that represents an asset bridged from Flow EVM such as an ERC20 /// or ERC721 token. diff --git a/cadence/contracts/bridge/interfaces/IEVMBridgeNFTMinter.cdc b/cadence/contracts/bridge/interfaces/IEVMBridgeNFTMinter.cdc index 976e47a9..93908c9a 100644 --- a/cadence/contracts/bridge/interfaces/IEVMBridgeNFTMinter.cdc +++ b/cadence/contracts/bridge/interfaces/IEVMBridgeNFTMinter.cdc @@ -1,4 +1,4 @@ -import NonFungibleToken from 0x1d7e57aa55817448 +import "NonFungibleToken" /// Contract interface enabling FlowEVMBridge to mint NFTs from implementing bridge contracts. /// diff --git a/cadence/contracts/bridge/interfaces/IEVMBridgeTokenMinter.cdc b/cadence/contracts/bridge/interfaces/IEVMBridgeTokenMinter.cdc index 2a44b568..f5ce9120 100644 --- a/cadence/contracts/bridge/interfaces/IEVMBridgeTokenMinter.cdc +++ b/cadence/contracts/bridge/interfaces/IEVMBridgeTokenMinter.cdc @@ -1,4 +1,4 @@ -import FungibleToken from 0xf233dcee88fe0abe +import "FungibleToken" /// Contract interface enabling FlowEVMBridge to mint fungible tokens from implementing bridge contracts. /// diff --git a/cadence/contracts/bridge/interfaces/IFlowEVMNFTBridge.cdc b/cadence/contracts/bridge/interfaces/IFlowEVMNFTBridge.cdc index 0dbcfd04..0dee5839 100644 --- a/cadence/contracts/bridge/interfaces/IFlowEVMNFTBridge.cdc +++ b/cadence/contracts/bridge/interfaces/IFlowEVMNFTBridge.cdc @@ -1,10 +1,10 @@ -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 +import "FungibleToken" +import "NonFungibleToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import CrossVMNFT from 0x1e4aa0b87d10b141 +import "FlowEVMBridgeConfig" +import "CrossVMNFT" access(all) contract interface IFlowEVMNFTBridge { diff --git a/cadence/contracts/bridge/interfaces/IFlowEVMTokenBridge.cdc b/cadence/contracts/bridge/interfaces/IFlowEVMTokenBridge.cdc index 942eb8fe..7033ebef 100644 --- a/cadence/contracts/bridge/interfaces/IFlowEVMTokenBridge.cdc +++ b/cadence/contracts/bridge/interfaces/IFlowEVMTokenBridge.cdc @@ -1,7 +1,7 @@ -import FungibleToken from 0xf233dcee88fe0abe -import NonFungibleToken from 0x1d7e57aa55817448 +import "FungibleToken" +import "NonFungibleToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" access(all) contract interface IFlowEVMTokenBridge { diff --git a/cadence/contracts/example-assets/ExampleNFT.cdc b/cadence/contracts/example-assets/ExampleNFT.cdc index 1576dbf5..1ae72dc9 100644 --- a/cadence/contracts/example-assets/ExampleNFT.cdc +++ b/cadence/contracts/example-assets/ExampleNFT.cdc @@ -10,9 +10,9 @@ * */ -import NonFungibleToken from 0x1d7e57aa55817448 -import ViewResolver from 0x1d7e57aa55817448 -import MetadataViews from 0x1d7e57aa55817448 +import "NonFungibleToken" +import "ViewResolver" +import "MetadataViews" access(all) contract ExampleNFT: NonFungibleToken { diff --git a/cadence/contracts/example-assets/ExampleToken.cdc b/cadence/contracts/example-assets/ExampleToken.cdc index e3c2d16f..91415bad 100644 --- a/cadence/contracts/example-assets/ExampleToken.cdc +++ b/cadence/contracts/example-assets/ExampleToken.cdc @@ -1,6 +1,6 @@ -import FungibleToken from 0xf233dcee88fe0abe -import MetadataViews from 0x1d7e57aa55817448 -import FungibleTokenMetadataViews from 0xf233dcee88fe0abe +import "FungibleToken" +import "MetadataViews" +import "FungibleTokenMetadataViews" access(all) contract ExampleToken: FungibleToken { diff --git a/cadence/contracts/handled-tokens/USDCFlow.cdc b/cadence/contracts/handled-tokens/USDCFlow.cdc index b0cc3e0c..0f2e680c 100644 --- a/cadence/contracts/handled-tokens/USDCFlow.cdc +++ b/cadence/contracts/handled-tokens/USDCFlow.cdc @@ -1,9 +1,9 @@ -import FungibleToken from 0xf233dcee88fe0abe -import FungibleTokenMetadataViews from 0xf233dcee88fe0abe -import MetadataViews from 0x1d7e57aa55817448 -import Burner from 0xf233dcee88fe0abe -import ViewResolver from 0x1d7e57aa55817448 -import FlowEVMBridgeHandlerInterfaces from 0x1e4aa0b87d10b141 +import "FungibleToken" +import "FungibleTokenMetadataViews" +import "MetadataViews" +import "Burner" +import "ViewResolver" +import "FlowEVMBridgeHandlerInterfaces" /// The `USDCFlow` smart contract is integrated directly /// with the Flow VM bridge as the bridged version of Flow EVM USDC diff --git a/cadence/contracts/templates/emulator/EVMBridgedNFTTemplate.cdc b/cadence/contracts/templates/emulator/EVMBridgedNFTTemplate.cdc index b3a32258..6b9744e0 100644 --- a/cadence/contracts/templates/emulator/EVMBridgedNFTTemplate.cdc +++ b/cadence/contracts/templates/emulator/EVMBridgedNFTTemplate.cdc @@ -1,20 +1,20 @@ -import NonFungibleToken from 0xf8d6e0586b0a20c7 -import MetadataViews from 0xf8d6e0586b0a20c7 -import ViewResolver from 0xf8d6e0586b0a20c7 -import FungibleToken from 0xee82856bf20e2aa6 -import FlowToken from 0x0ae53cb6e3f42a79 - -import EVM from 0xf8d6e0586b0a20c7 - -import ICrossVM from 0xf8d6e0586b0a20c7 -import ICrossVMAsset from 0xf8d6e0586b0a20c7 -import IEVMBridgeNFTMinter from 0xf8d6e0586b0a20c7 -import FlowEVMBridgeNFTEscrow from 0xf8d6e0586b0a20c7 -import FlowEVMBridgeConfig from 0xf8d6e0586b0a20c7 -import FlowEVMBridgeUtils from 0xf8d6e0586b0a20c7 -import FlowEVMBridge from 0xf8d6e0586b0a20c7 -import CrossVMNFT from 0xf8d6e0586b0a20c7 -import FlowEVMBridgeResolver from 0xf8d6e0586b0a20c7 +import "NonFungibleToken" +import "MetadataViews" +import "ViewResolver" +import "FungibleToken" +import "FlowToken" + +import "EVM" + +import "ICrossVM" +import "ICrossVMAsset" +import "IEVMBridgeNFTMinter" +import "FlowEVMBridgeNFTEscrow" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "FlowEVMBridge" +import "CrossVMNFT" +import "FlowEVMBridgeResolver" /// This contract is a template used by FlowEVMBridge to define EVM-native NFTs bridged from Flow EVM to Flow. /// Upon deployment of this contract, the contract name is derived as a function of the asset type (here an ERC721 aka diff --git a/cadence/contracts/templates/emulator/EVMBridgedTokenTemplate.cdc b/cadence/contracts/templates/emulator/EVMBridgedTokenTemplate.cdc index b8169d40..9527e955 100644 --- a/cadence/contracts/templates/emulator/EVMBridgedTokenTemplate.cdc +++ b/cadence/contracts/templates/emulator/EVMBridgedTokenTemplate.cdc @@ -1,21 +1,21 @@ -import NonFungibleToken from 0xf8d6e0586b0a20c7 -import MetadataViews from 0xf8d6e0586b0a20c7 -import FungibleTokenMetadataViews from 0xee82856bf20e2aa6 -import ViewResolver from 0xf8d6e0586b0a20c7 -import FungibleToken from 0xee82856bf20e2aa6 -import FlowToken from 0x0ae53cb6e3f42a79 +import "NonFungibleToken" +import "MetadataViews" +import "FungibleTokenMetadataViews" +import "ViewResolver" +import "FungibleToken" +import "FlowToken" -import EVM from 0xf8d6e0586b0a20c7 +import "EVM" -import ICrossVM from 0xf8d6e0586b0a20c7 -import ICrossVMAsset from 0xf8d6e0586b0a20c7 -import IEVMBridgeTokenMinter from 0xf8d6e0586b0a20c7 -import FlowEVMBridgeTokenEscrow from 0xf8d6e0586b0a20c7 -import FlowEVMBridgeConfig from 0xf8d6e0586b0a20c7 -import FlowEVMBridgeUtils from 0xf8d6e0586b0a20c7 -import FlowEVMBridge from 0xf8d6e0586b0a20c7 -import CrossVMToken from 0xf8d6e0586b0a20c7 -import FlowEVMBridgeResolver from 0xf8d6e0586b0a20c7 +import "ICrossVM" +import "ICrossVMAsset" +import "IEVMBridgeTokenMinter" +import "FlowEVMBridgeTokenEscrow" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "FlowEVMBridge" +import "CrossVMToken" +import "FlowEVMBridgeResolver" /// This contract is a template used by FlowEVMBridge to define EVM-native fungible tokens bridged from Flow EVM to /// Cadence. Upon deployment of this contract, the contract name is derived as a function of the asset type (here an diff --git a/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc b/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc index 754bf9e2..6b9744e0 100644 --- a/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc +++ b/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc @@ -1,20 +1,20 @@ -import NonFungibleToken from 0x1d7e57aa55817448 -import MetadataViews from 0x1d7e57aa55817448 -import ViewResolver from 0x1d7e57aa55817448 -import FungibleToken from 0xf233dcee88fe0abe -import FlowToken from 0x1654653399040a61 - -import EVM from 0xe467b9dd11fa00df - -import ICrossVM from 0x1e4aa0b87d10b141 -import ICrossVMAsset from 0x1e4aa0b87d10b141 -import IEVMBridgeNFTMinter from 0x1e4aa0b87d10b141 -import FlowEVMBridgeNFTEscrow from 0x1e4aa0b87d10b141 -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 -import FlowEVMBridge from 0x1e4aa0b87d10b141 -import CrossVMNFT from 0x1e4aa0b87d10b141 -import FlowEVMBridgeResolver from 0x1e4aa0b87d10b141 +import "NonFungibleToken" +import "MetadataViews" +import "ViewResolver" +import "FungibleToken" +import "FlowToken" + +import "EVM" + +import "ICrossVM" +import "ICrossVMAsset" +import "IEVMBridgeNFTMinter" +import "FlowEVMBridgeNFTEscrow" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "FlowEVMBridge" +import "CrossVMNFT" +import "FlowEVMBridgeResolver" /// This contract is a template used by FlowEVMBridge to define EVM-native NFTs bridged from Flow EVM to Flow. /// Upon deployment of this contract, the contract name is derived as a function of the asset type (here an ERC721 aka diff --git a/cadence/contracts/templates/mainnet/EVMBridgedTokenTemplate.cdc b/cadence/contracts/templates/mainnet/EVMBridgedTokenTemplate.cdc index c1e6bf09..66b3752f 100644 --- a/cadence/contracts/templates/mainnet/EVMBridgedTokenTemplate.cdc +++ b/cadence/contracts/templates/mainnet/EVMBridgedTokenTemplate.cdc @@ -1,21 +1,21 @@ -import NonFungibleToken from 0x1d7e57aa55817448 -import MetadataViews from 0x1d7e57aa55817448 -import ViewResolver from 0x1d7e57aa55817448 -import FungibleToken from 0xf233dcee88fe0abe -import FungibleTokenMetadataViews from 0xf233dcee88fe0abe -import FlowToken from 0x1654653399040a61 +import "NonFungibleToken" +import "MetadataViews" +import "ViewResolver" +import "FungibleToken" +import "FungibleTokenMetadataViews" +import "FlowToken" -import EVM from 0xe467b9dd11fa00df +import "EVM" -import ICrossVM from 0x1e4aa0b87d10b141 -import ICrossVMAsset from 0x1e4aa0b87d10b141 -import IEVMBridgeTokenMinter from 0x1e4aa0b87d10b141 -import FlowEVMBridgeTokenEscrow from 0x1e4aa0b87d10b141 -import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 -import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 -import FlowEVMBridge from 0x1e4aa0b87d10b141 -import CrossVMToken from 0x1e4aa0b87d10b141 -import FlowEVMBridgeResolver from 0x1e4aa0b87d10b141 +import "ICrossVM" +import "ICrossVMAsset" +import "IEVMBridgeTokenMinter" +import "FlowEVMBridgeTokenEscrow" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "FlowEVMBridge" +import "CrossVMToken" +import "FlowEVMBridgeResolver" /// This contract is a template used by FlowEVMBridge to define EVM-native fungible tokens bridged from Flow EVM to /// Cadence. Upon deployment of this contract, the contract name is derived as a function of the asset type (here an diff --git a/cadence/contracts/templates/testing/EVMBridgedNFTTemplate.cdc b/cadence/contracts/templates/testing/EVMBridgedNFTTemplate.cdc index 4634f5df..6b9744e0 100644 --- a/cadence/contracts/templates/testing/EVMBridgedNFTTemplate.cdc +++ b/cadence/contracts/templates/testing/EVMBridgedNFTTemplate.cdc @@ -1,20 +1,20 @@ -import NonFungibleToken from 0x0000000000000001 -import MetadataViews from 0x0000000000000001 -import ViewResolver from 0x0000000000000001 -import FungibleToken from 0x0000000000000002 -import FlowToken from 0x0000000000000003 - -import EVM from 0x0000000000000001 - -import ICrossVM from 0x0000000000000007 -import ICrossVMAsset from 0x0000000000000007 -import IEVMBridgeNFTMinter from 0x0000000000000007 -import FlowEVMBridgeNFTEscrow from 0x0000000000000007 -import FlowEVMBridgeConfig from 0x0000000000000007 -import FlowEVMBridgeUtils from 0x0000000000000007 -import FlowEVMBridge from 0x0000000000000007 -import CrossVMNFT from 0x0000000000000007 -import FlowEVMBridgeResolver from 0x0000000000000007 +import "NonFungibleToken" +import "MetadataViews" +import "ViewResolver" +import "FungibleToken" +import "FlowToken" + +import "EVM" + +import "ICrossVM" +import "ICrossVMAsset" +import "IEVMBridgeNFTMinter" +import "FlowEVMBridgeNFTEscrow" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "FlowEVMBridge" +import "CrossVMNFT" +import "FlowEVMBridgeResolver" /// This contract is a template used by FlowEVMBridge to define EVM-native NFTs bridged from Flow EVM to Flow. /// Upon deployment of this contract, the contract name is derived as a function of the asset type (here an ERC721 aka diff --git a/cadence/contracts/templates/testing/EVMBridgedTokenTemplate.cdc b/cadence/contracts/templates/testing/EVMBridgedTokenTemplate.cdc index fe64ad96..9527e955 100644 --- a/cadence/contracts/templates/testing/EVMBridgedTokenTemplate.cdc +++ b/cadence/contracts/templates/testing/EVMBridgedTokenTemplate.cdc @@ -1,21 +1,21 @@ -import NonFungibleToken from 0x0000000000000001 -import MetadataViews from 0x0000000000000001 -import FungibleTokenMetadataViews from 0x0000000000000002 -import ViewResolver from 0x0000000000000001 -import FungibleToken from 0x0000000000000002 -import FlowToken from 0x0000000000000003 +import "NonFungibleToken" +import "MetadataViews" +import "FungibleTokenMetadataViews" +import "ViewResolver" +import "FungibleToken" +import "FlowToken" -import EVM from 0x0000000000000001 +import "EVM" -import ICrossVM from 0x0000000000000007 -import ICrossVMAsset from 0x0000000000000007 -import IEVMBridgeTokenMinter from 0x0000000000000007 -import FlowEVMBridgeTokenEscrow from 0x0000000000000007 -import FlowEVMBridgeConfig from 0x0000000000000007 -import FlowEVMBridgeUtils from 0x0000000000000007 -import FlowEVMBridge from 0x0000000000000007 -import CrossVMToken from 0x0000000000000007 -import FlowEVMBridgeResolver from 0x0000000000000007 +import "ICrossVM" +import "ICrossVMAsset" +import "IEVMBridgeTokenMinter" +import "FlowEVMBridgeTokenEscrow" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "FlowEVMBridge" +import "CrossVMToken" +import "FlowEVMBridgeResolver" /// This contract is a template used by FlowEVMBridge to define EVM-native fungible tokens bridged from Flow EVM to /// Cadence. Upon deployment of this contract, the contract name is derived as a function of the asset type (here an diff --git a/cadence/contracts/templates/testnet/EVMBridgedNFTTemplate.cdc b/cadence/contracts/templates/testnet/EVMBridgedNFTTemplate.cdc index cd8e2128..6b9744e0 100644 --- a/cadence/contracts/templates/testnet/EVMBridgedNFTTemplate.cdc +++ b/cadence/contracts/templates/testnet/EVMBridgedNFTTemplate.cdc @@ -1,20 +1,20 @@ -import NonFungibleToken from 0x631e88ae7f1d7c20 -import MetadataViews from 0x631e88ae7f1d7c20 -import ViewResolver from 0x631e88ae7f1d7c20 -import FungibleToken from 0x9a0766d93b6608b7 -import FlowToken from 0x7e60df042a9c0868 - -import EVM from 0x8c5303eaa26202d6 - -import ICrossVM from 0xdfc20aee650fcbdf -import ICrossVMAsset from 0xdfc20aee650fcbdf -import IEVMBridgeNFTMinter from 0xdfc20aee650fcbdf -import FlowEVMBridgeNFTEscrow from 0xdfc20aee650fcbdf -import FlowEVMBridgeConfig from 0xdfc20aee650fcbdf -import FlowEVMBridgeUtils from 0xdfc20aee650fcbdf -import FlowEVMBridge from 0xdfc20aee650fcbdf -import CrossVMNFT from 0xdfc20aee650fcbdf -import FlowEVMBridgeResolver from 0xdfc20aee650fcbdf +import "NonFungibleToken" +import "MetadataViews" +import "ViewResolver" +import "FungibleToken" +import "FlowToken" + +import "EVM" + +import "ICrossVM" +import "ICrossVMAsset" +import "IEVMBridgeNFTMinter" +import "FlowEVMBridgeNFTEscrow" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "FlowEVMBridge" +import "CrossVMNFT" +import "FlowEVMBridgeResolver" /// This contract is a template used by FlowEVMBridge to define EVM-native NFTs bridged from Flow EVM to Flow. /// Upon deployment of this contract, the contract name is derived as a function of the asset type (here an ERC721 aka diff --git a/cadence/contracts/templates/testnet/EVMBridgedTokenTemplate.cdc b/cadence/contracts/templates/testnet/EVMBridgedTokenTemplate.cdc index 42f76ac2..9527e955 100644 --- a/cadence/contracts/templates/testnet/EVMBridgedTokenTemplate.cdc +++ b/cadence/contracts/templates/testnet/EVMBridgedTokenTemplate.cdc @@ -1,21 +1,21 @@ -import NonFungibleToken from 0x631e88ae7f1d7c20 -import MetadataViews from 0x631e88ae7f1d7c20 -import FungibleTokenMetadataViews from 0x9a0766d93b6608b7 -import ViewResolver from 0x631e88ae7f1d7c20 -import FungibleToken from 0x9a0766d93b6608b7 -import FlowToken from 0x7e60df042a9c0868 +import "NonFungibleToken" +import "MetadataViews" +import "FungibleTokenMetadataViews" +import "ViewResolver" +import "FungibleToken" +import "FlowToken" -import EVM from 0x8c5303eaa26202d6 +import "EVM" -import ICrossVM from 0xdfc20aee650fcbdf -import ICrossVMAsset from 0xdfc20aee650fcbdf -import IEVMBridgeTokenMinter from 0xdfc20aee650fcbdf -import FlowEVMBridgeTokenEscrow from 0xdfc20aee650fcbdf -import FlowEVMBridgeConfig from 0xdfc20aee650fcbdf -import FlowEVMBridgeUtils from 0xdfc20aee650fcbdf -import FlowEVMBridge from 0xdfc20aee650fcbdf -import CrossVMToken from 0xdfc20aee650fcbdf -import FlowEVMBridgeResolver from 0xdfc20aee650fcbdf +import "ICrossVM" +import "ICrossVMAsset" +import "IEVMBridgeTokenMinter" +import "FlowEVMBridgeTokenEscrow" +import "FlowEVMBridgeConfig" +import "FlowEVMBridgeUtils" +import "FlowEVMBridge" +import "CrossVMToken" +import "FlowEVMBridgeResolver" /// This contract is a template used by FlowEVMBridge to define EVM-native fungible tokens bridged from Flow EVM to /// Cadence. Upon deployment of this contract, the contract name is derived as a function of the asset type (here an diff --git a/cadence/contracts/utils/ScopedFTProviders.cdc b/cadence/contracts/utils/ScopedFTProviders.cdc index a6ff495f..77c76ced 100644 --- a/cadence/contracts/utils/ScopedFTProviders.cdc +++ b/cadence/contracts/utils/ScopedFTProviders.cdc @@ -1,5 +1,5 @@ -import FungibleToken from 0xf233dcee88fe0abe -import StringUtils from 0x1e4aa0b87d10b141 +import "FungibleToken" +import "StringUtils" // Copied from https://github.com/green-goo-dao/flow-utils/blob/crescendo/contracts/ScopedFTProviders.cdc with minor changes // Special thanks to the Green Goo Dao contributors for creating this contract diff --git a/cadence/contracts/utils/Serialize.cdc b/cadence/contracts/utils/Serialize.cdc index a70f4b8e..41c9892f 100644 --- a/cadence/contracts/utils/Serialize.cdc +++ b/cadence/contracts/utils/Serialize.cdc @@ -1,6 +1,6 @@ -import ViewResolver from 0x1d7e57aa55817448 -import MetadataViews from 0x1d7e57aa55817448 -import NonFungibleToken from 0x1d7e57aa55817448 +import "ViewResolver" +import "MetadataViews" +import "NonFungibleToken" /// This contract is a utility for serializing primitive types, arrays, and common metadata mapping formats to JSON /// compatible strings. Also included are interfaces enabling custom serialization for structs and resources. diff --git a/cadence/contracts/utils/SerializeMetadata.cdc b/cadence/contracts/utils/SerializeMetadata.cdc index f948b582..1ceca382 100644 --- a/cadence/contracts/utils/SerializeMetadata.cdc +++ b/cadence/contracts/utils/SerializeMetadata.cdc @@ -1,9 +1,9 @@ -import ViewResolver from 0x1d7e57aa55817448 -import MetadataViews from 0x1d7e57aa55817448 -import NonFungibleToken from 0x1d7e57aa55817448 -import FungibleTokenMetadataViews from 0xf233dcee88fe0abe +import "ViewResolver" +import "MetadataViews" +import "NonFungibleToken" +import "FungibleTokenMetadataViews" -import Serialize from 0x1e4aa0b87d10b141 +import "Serialize" /// This contract defines methods for serializing NFT metadata as a JSON compatible string, according to the common /// OpenSea metadata format. NFTs and metadata views can be serialized by reference via contract methods. diff --git a/cadence/contracts/utils/StringUtils.cdc b/cadence/contracts/utils/StringUtils.cdc index ffce9f0f..4af734e6 100644 --- a/cadence/contracts/utils/StringUtils.cdc +++ b/cadence/contracts/utils/StringUtils.cdc @@ -1,4 +1,4 @@ -import ArrayUtils from 0x1e4aa0b87d10b141 +import "ArrayUtils" // Copied from https://github.com/green-goo-dao/flow-utils/blob/crescendo/contracts/StringUtils.cdc // Special thanks to the Green Goo Dao contributors for creating this contract From 27fcdc1b860c831362d07a5611e82c2927a69f17 Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:59:05 -0400 Subject: [PATCH 3/4] chore: replace all address-based imports with string imports across all cdc files --- .../tests/contracts/ExampleNFT_updated.cdc | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cadence/tests/contracts/ExampleNFT_updated.cdc b/cadence/tests/contracts/ExampleNFT_updated.cdc index a3b68b87..872aef7a 100644 --- a/cadence/tests/contracts/ExampleNFT_updated.cdc +++ b/cadence/tests/contracts/ExampleNFT_updated.cdc @@ -10,18 +10,18 @@ * */ -import NonFungibleToken from 0x0000000000000001 -import ViewResolver from 0x0000000000000001 -import MetadataViews from 0x0000000000000001 -import CrossVMMetadataViews from 0x0000000000000001 - -import EVM from 0x0000000000000001 - -import ICrossVM from 0x0000000000000007 -import ICrossVMAsset from 0x0000000000000007 -import SerializeMetadata from 0x0000000000000007 -import FlowEVMBridgeCustomAssociationTypes from 0x0000000000000007 -import FlowEVMBridgeUtils from 0x0000000000000007 +import "NonFungibleToken" +import "ViewResolver" +import "MetadataViews" +import "CrossVMMetadataViews" + +import "EVM" + +import "ICrossVM" +import "ICrossVMAsset" +import "SerializeMetadata" +import "FlowEVMBridgeCustomAssociationTypes" +import "FlowEVMBridgeUtils" /// THIS CONTRACT IS USED FOR TESTING PURPOSES ONLY access(all) contract ExampleNFT: NonFungibleToken { From 59a307841b6b1a32f081ec9b88ca01a50a7bf880 Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Thu, 16 Apr 2026 19:30:12 -0400 Subject: [PATCH 4/4] chore: overwrite templates and tests/contracts with main versions --- .../emulator/EVMBridgedNFTTemplate.cdc | 34 +++++++++---------- .../emulator/EVMBridgedTokenTemplate.cdc | 32 ++++++++--------- .../mainnet/EVMBridgedNFTTemplate.cdc | 34 +++++++++---------- .../mainnet/EVMBridgedTokenTemplate.cdc | 32 ++++++++--------- .../testing/EVMBridgedNFTTemplate.cdc | 34 +++++++++---------- .../testing/EVMBridgedTokenTemplate.cdc | 32 ++++++++--------- .../testnet/EVMBridgedNFTTemplate.cdc | 34 +++++++++---------- .../testnet/EVMBridgedTokenTemplate.cdc | 32 ++++++++--------- .../tests/contracts/ExampleNFT_updated.cdc | 24 ++++++------- 9 files changed, 144 insertions(+), 144 deletions(-) diff --git a/cadence/contracts/templates/emulator/EVMBridgedNFTTemplate.cdc b/cadence/contracts/templates/emulator/EVMBridgedNFTTemplate.cdc index 6b9744e0..b3a32258 100644 --- a/cadence/contracts/templates/emulator/EVMBridgedNFTTemplate.cdc +++ b/cadence/contracts/templates/emulator/EVMBridgedNFTTemplate.cdc @@ -1,20 +1,20 @@ -import "NonFungibleToken" -import "MetadataViews" -import "ViewResolver" -import "FungibleToken" -import "FlowToken" - -import "EVM" - -import "ICrossVM" -import "ICrossVMAsset" -import "IEVMBridgeNFTMinter" -import "FlowEVMBridgeNFTEscrow" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "FlowEVMBridge" -import "CrossVMNFT" -import "FlowEVMBridgeResolver" +import NonFungibleToken from 0xf8d6e0586b0a20c7 +import MetadataViews from 0xf8d6e0586b0a20c7 +import ViewResolver from 0xf8d6e0586b0a20c7 +import FungibleToken from 0xee82856bf20e2aa6 +import FlowToken from 0x0ae53cb6e3f42a79 + +import EVM from 0xf8d6e0586b0a20c7 + +import ICrossVM from 0xf8d6e0586b0a20c7 +import ICrossVMAsset from 0xf8d6e0586b0a20c7 +import IEVMBridgeNFTMinter from 0xf8d6e0586b0a20c7 +import FlowEVMBridgeNFTEscrow from 0xf8d6e0586b0a20c7 +import FlowEVMBridgeConfig from 0xf8d6e0586b0a20c7 +import FlowEVMBridgeUtils from 0xf8d6e0586b0a20c7 +import FlowEVMBridge from 0xf8d6e0586b0a20c7 +import CrossVMNFT from 0xf8d6e0586b0a20c7 +import FlowEVMBridgeResolver from 0xf8d6e0586b0a20c7 /// This contract is a template used by FlowEVMBridge to define EVM-native NFTs bridged from Flow EVM to Flow. /// Upon deployment of this contract, the contract name is derived as a function of the asset type (here an ERC721 aka diff --git a/cadence/contracts/templates/emulator/EVMBridgedTokenTemplate.cdc b/cadence/contracts/templates/emulator/EVMBridgedTokenTemplate.cdc index 9527e955..b8169d40 100644 --- a/cadence/contracts/templates/emulator/EVMBridgedTokenTemplate.cdc +++ b/cadence/contracts/templates/emulator/EVMBridgedTokenTemplate.cdc @@ -1,21 +1,21 @@ -import "NonFungibleToken" -import "MetadataViews" -import "FungibleTokenMetadataViews" -import "ViewResolver" -import "FungibleToken" -import "FlowToken" +import NonFungibleToken from 0xf8d6e0586b0a20c7 +import MetadataViews from 0xf8d6e0586b0a20c7 +import FungibleTokenMetadataViews from 0xee82856bf20e2aa6 +import ViewResolver from 0xf8d6e0586b0a20c7 +import FungibleToken from 0xee82856bf20e2aa6 +import FlowToken from 0x0ae53cb6e3f42a79 -import "EVM" +import EVM from 0xf8d6e0586b0a20c7 -import "ICrossVM" -import "ICrossVMAsset" -import "IEVMBridgeTokenMinter" -import "FlowEVMBridgeTokenEscrow" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "FlowEVMBridge" -import "CrossVMToken" -import "FlowEVMBridgeResolver" +import ICrossVM from 0xf8d6e0586b0a20c7 +import ICrossVMAsset from 0xf8d6e0586b0a20c7 +import IEVMBridgeTokenMinter from 0xf8d6e0586b0a20c7 +import FlowEVMBridgeTokenEscrow from 0xf8d6e0586b0a20c7 +import FlowEVMBridgeConfig from 0xf8d6e0586b0a20c7 +import FlowEVMBridgeUtils from 0xf8d6e0586b0a20c7 +import FlowEVMBridge from 0xf8d6e0586b0a20c7 +import CrossVMToken from 0xf8d6e0586b0a20c7 +import FlowEVMBridgeResolver from 0xf8d6e0586b0a20c7 /// This contract is a template used by FlowEVMBridge to define EVM-native fungible tokens bridged from Flow EVM to /// Cadence. Upon deployment of this contract, the contract name is derived as a function of the asset type (here an diff --git a/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc b/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc index 6b9744e0..754bf9e2 100644 --- a/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc +++ b/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc @@ -1,20 +1,20 @@ -import "NonFungibleToken" -import "MetadataViews" -import "ViewResolver" -import "FungibleToken" -import "FlowToken" - -import "EVM" - -import "ICrossVM" -import "ICrossVMAsset" -import "IEVMBridgeNFTMinter" -import "FlowEVMBridgeNFTEscrow" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "FlowEVMBridge" -import "CrossVMNFT" -import "FlowEVMBridgeResolver" +import NonFungibleToken from 0x1d7e57aa55817448 +import MetadataViews from 0x1d7e57aa55817448 +import ViewResolver from 0x1d7e57aa55817448 +import FungibleToken from 0xf233dcee88fe0abe +import FlowToken from 0x1654653399040a61 + +import EVM from 0xe467b9dd11fa00df + +import ICrossVM from 0x1e4aa0b87d10b141 +import ICrossVMAsset from 0x1e4aa0b87d10b141 +import IEVMBridgeNFTMinter from 0x1e4aa0b87d10b141 +import FlowEVMBridgeNFTEscrow from 0x1e4aa0b87d10b141 +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 +import FlowEVMBridge from 0x1e4aa0b87d10b141 +import CrossVMNFT from 0x1e4aa0b87d10b141 +import FlowEVMBridgeResolver from 0x1e4aa0b87d10b141 /// This contract is a template used by FlowEVMBridge to define EVM-native NFTs bridged from Flow EVM to Flow. /// Upon deployment of this contract, the contract name is derived as a function of the asset type (here an ERC721 aka diff --git a/cadence/contracts/templates/mainnet/EVMBridgedTokenTemplate.cdc b/cadence/contracts/templates/mainnet/EVMBridgedTokenTemplate.cdc index 66b3752f..c1e6bf09 100644 --- a/cadence/contracts/templates/mainnet/EVMBridgedTokenTemplate.cdc +++ b/cadence/contracts/templates/mainnet/EVMBridgedTokenTemplate.cdc @@ -1,21 +1,21 @@ -import "NonFungibleToken" -import "MetadataViews" -import "ViewResolver" -import "FungibleToken" -import "FungibleTokenMetadataViews" -import "FlowToken" +import NonFungibleToken from 0x1d7e57aa55817448 +import MetadataViews from 0x1d7e57aa55817448 +import ViewResolver from 0x1d7e57aa55817448 +import FungibleToken from 0xf233dcee88fe0abe +import FungibleTokenMetadataViews from 0xf233dcee88fe0abe +import FlowToken from 0x1654653399040a61 -import "EVM" +import EVM from 0xe467b9dd11fa00df -import "ICrossVM" -import "ICrossVMAsset" -import "IEVMBridgeTokenMinter" -import "FlowEVMBridgeTokenEscrow" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "FlowEVMBridge" -import "CrossVMToken" -import "FlowEVMBridgeResolver" +import ICrossVM from 0x1e4aa0b87d10b141 +import ICrossVMAsset from 0x1e4aa0b87d10b141 +import IEVMBridgeTokenMinter from 0x1e4aa0b87d10b141 +import FlowEVMBridgeTokenEscrow from 0x1e4aa0b87d10b141 +import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141 +import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141 +import FlowEVMBridge from 0x1e4aa0b87d10b141 +import CrossVMToken from 0x1e4aa0b87d10b141 +import FlowEVMBridgeResolver from 0x1e4aa0b87d10b141 /// This contract is a template used by FlowEVMBridge to define EVM-native fungible tokens bridged from Flow EVM to /// Cadence. Upon deployment of this contract, the contract name is derived as a function of the asset type (here an diff --git a/cadence/contracts/templates/testing/EVMBridgedNFTTemplate.cdc b/cadence/contracts/templates/testing/EVMBridgedNFTTemplate.cdc index 6b9744e0..4634f5df 100644 --- a/cadence/contracts/templates/testing/EVMBridgedNFTTemplate.cdc +++ b/cadence/contracts/templates/testing/EVMBridgedNFTTemplate.cdc @@ -1,20 +1,20 @@ -import "NonFungibleToken" -import "MetadataViews" -import "ViewResolver" -import "FungibleToken" -import "FlowToken" - -import "EVM" - -import "ICrossVM" -import "ICrossVMAsset" -import "IEVMBridgeNFTMinter" -import "FlowEVMBridgeNFTEscrow" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "FlowEVMBridge" -import "CrossVMNFT" -import "FlowEVMBridgeResolver" +import NonFungibleToken from 0x0000000000000001 +import MetadataViews from 0x0000000000000001 +import ViewResolver from 0x0000000000000001 +import FungibleToken from 0x0000000000000002 +import FlowToken from 0x0000000000000003 + +import EVM from 0x0000000000000001 + +import ICrossVM from 0x0000000000000007 +import ICrossVMAsset from 0x0000000000000007 +import IEVMBridgeNFTMinter from 0x0000000000000007 +import FlowEVMBridgeNFTEscrow from 0x0000000000000007 +import FlowEVMBridgeConfig from 0x0000000000000007 +import FlowEVMBridgeUtils from 0x0000000000000007 +import FlowEVMBridge from 0x0000000000000007 +import CrossVMNFT from 0x0000000000000007 +import FlowEVMBridgeResolver from 0x0000000000000007 /// This contract is a template used by FlowEVMBridge to define EVM-native NFTs bridged from Flow EVM to Flow. /// Upon deployment of this contract, the contract name is derived as a function of the asset type (here an ERC721 aka diff --git a/cadence/contracts/templates/testing/EVMBridgedTokenTemplate.cdc b/cadence/contracts/templates/testing/EVMBridgedTokenTemplate.cdc index 9527e955..fe64ad96 100644 --- a/cadence/contracts/templates/testing/EVMBridgedTokenTemplate.cdc +++ b/cadence/contracts/templates/testing/EVMBridgedTokenTemplate.cdc @@ -1,21 +1,21 @@ -import "NonFungibleToken" -import "MetadataViews" -import "FungibleTokenMetadataViews" -import "ViewResolver" -import "FungibleToken" -import "FlowToken" +import NonFungibleToken from 0x0000000000000001 +import MetadataViews from 0x0000000000000001 +import FungibleTokenMetadataViews from 0x0000000000000002 +import ViewResolver from 0x0000000000000001 +import FungibleToken from 0x0000000000000002 +import FlowToken from 0x0000000000000003 -import "EVM" +import EVM from 0x0000000000000001 -import "ICrossVM" -import "ICrossVMAsset" -import "IEVMBridgeTokenMinter" -import "FlowEVMBridgeTokenEscrow" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "FlowEVMBridge" -import "CrossVMToken" -import "FlowEVMBridgeResolver" +import ICrossVM from 0x0000000000000007 +import ICrossVMAsset from 0x0000000000000007 +import IEVMBridgeTokenMinter from 0x0000000000000007 +import FlowEVMBridgeTokenEscrow from 0x0000000000000007 +import FlowEVMBridgeConfig from 0x0000000000000007 +import FlowEVMBridgeUtils from 0x0000000000000007 +import FlowEVMBridge from 0x0000000000000007 +import CrossVMToken from 0x0000000000000007 +import FlowEVMBridgeResolver from 0x0000000000000007 /// This contract is a template used by FlowEVMBridge to define EVM-native fungible tokens bridged from Flow EVM to /// Cadence. Upon deployment of this contract, the contract name is derived as a function of the asset type (here an diff --git a/cadence/contracts/templates/testnet/EVMBridgedNFTTemplate.cdc b/cadence/contracts/templates/testnet/EVMBridgedNFTTemplate.cdc index 6b9744e0..cd8e2128 100644 --- a/cadence/contracts/templates/testnet/EVMBridgedNFTTemplate.cdc +++ b/cadence/contracts/templates/testnet/EVMBridgedNFTTemplate.cdc @@ -1,20 +1,20 @@ -import "NonFungibleToken" -import "MetadataViews" -import "ViewResolver" -import "FungibleToken" -import "FlowToken" - -import "EVM" - -import "ICrossVM" -import "ICrossVMAsset" -import "IEVMBridgeNFTMinter" -import "FlowEVMBridgeNFTEscrow" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "FlowEVMBridge" -import "CrossVMNFT" -import "FlowEVMBridgeResolver" +import NonFungibleToken from 0x631e88ae7f1d7c20 +import MetadataViews from 0x631e88ae7f1d7c20 +import ViewResolver from 0x631e88ae7f1d7c20 +import FungibleToken from 0x9a0766d93b6608b7 +import FlowToken from 0x7e60df042a9c0868 + +import EVM from 0x8c5303eaa26202d6 + +import ICrossVM from 0xdfc20aee650fcbdf +import ICrossVMAsset from 0xdfc20aee650fcbdf +import IEVMBridgeNFTMinter from 0xdfc20aee650fcbdf +import FlowEVMBridgeNFTEscrow from 0xdfc20aee650fcbdf +import FlowEVMBridgeConfig from 0xdfc20aee650fcbdf +import FlowEVMBridgeUtils from 0xdfc20aee650fcbdf +import FlowEVMBridge from 0xdfc20aee650fcbdf +import CrossVMNFT from 0xdfc20aee650fcbdf +import FlowEVMBridgeResolver from 0xdfc20aee650fcbdf /// This contract is a template used by FlowEVMBridge to define EVM-native NFTs bridged from Flow EVM to Flow. /// Upon deployment of this contract, the contract name is derived as a function of the asset type (here an ERC721 aka diff --git a/cadence/contracts/templates/testnet/EVMBridgedTokenTemplate.cdc b/cadence/contracts/templates/testnet/EVMBridgedTokenTemplate.cdc index 9527e955..42f76ac2 100644 --- a/cadence/contracts/templates/testnet/EVMBridgedTokenTemplate.cdc +++ b/cadence/contracts/templates/testnet/EVMBridgedTokenTemplate.cdc @@ -1,21 +1,21 @@ -import "NonFungibleToken" -import "MetadataViews" -import "FungibleTokenMetadataViews" -import "ViewResolver" -import "FungibleToken" -import "FlowToken" +import NonFungibleToken from 0x631e88ae7f1d7c20 +import MetadataViews from 0x631e88ae7f1d7c20 +import FungibleTokenMetadataViews from 0x9a0766d93b6608b7 +import ViewResolver from 0x631e88ae7f1d7c20 +import FungibleToken from 0x9a0766d93b6608b7 +import FlowToken from 0x7e60df042a9c0868 -import "EVM" +import EVM from 0x8c5303eaa26202d6 -import "ICrossVM" -import "ICrossVMAsset" -import "IEVMBridgeTokenMinter" -import "FlowEVMBridgeTokenEscrow" -import "FlowEVMBridgeConfig" -import "FlowEVMBridgeUtils" -import "FlowEVMBridge" -import "CrossVMToken" -import "FlowEVMBridgeResolver" +import ICrossVM from 0xdfc20aee650fcbdf +import ICrossVMAsset from 0xdfc20aee650fcbdf +import IEVMBridgeTokenMinter from 0xdfc20aee650fcbdf +import FlowEVMBridgeTokenEscrow from 0xdfc20aee650fcbdf +import FlowEVMBridgeConfig from 0xdfc20aee650fcbdf +import FlowEVMBridgeUtils from 0xdfc20aee650fcbdf +import FlowEVMBridge from 0xdfc20aee650fcbdf +import CrossVMToken from 0xdfc20aee650fcbdf +import FlowEVMBridgeResolver from 0xdfc20aee650fcbdf /// This contract is a template used by FlowEVMBridge to define EVM-native fungible tokens bridged from Flow EVM to /// Cadence. Upon deployment of this contract, the contract name is derived as a function of the asset type (here an diff --git a/cadence/tests/contracts/ExampleNFT_updated.cdc b/cadence/tests/contracts/ExampleNFT_updated.cdc index 872aef7a..a3b68b87 100644 --- a/cadence/tests/contracts/ExampleNFT_updated.cdc +++ b/cadence/tests/contracts/ExampleNFT_updated.cdc @@ -10,18 +10,18 @@ * */ -import "NonFungibleToken" -import "ViewResolver" -import "MetadataViews" -import "CrossVMMetadataViews" - -import "EVM" - -import "ICrossVM" -import "ICrossVMAsset" -import "SerializeMetadata" -import "FlowEVMBridgeCustomAssociationTypes" -import "FlowEVMBridgeUtils" +import NonFungibleToken from 0x0000000000000001 +import ViewResolver from 0x0000000000000001 +import MetadataViews from 0x0000000000000001 +import CrossVMMetadataViews from 0x0000000000000001 + +import EVM from 0x0000000000000001 + +import ICrossVM from 0x0000000000000007 +import ICrossVMAsset from 0x0000000000000007 +import SerializeMetadata from 0x0000000000000007 +import FlowEVMBridgeCustomAssociationTypes from 0x0000000000000007 +import FlowEVMBridgeUtils from 0x0000000000000007 /// THIS CONTRACT IS USED FOR TESTING PURPOSES ONLY access(all) contract ExampleNFT: NonFungibleToken {