Skip to content

Commit

Permalink
move EVMAddress de/serialization to EVMUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
sisyphusSmiling committed Apr 16, 2024
1 parent 7ea5ef0 commit c987f43
Show file tree
Hide file tree
Showing 27 changed files with 82 additions and 106 deletions.
16 changes: 5 additions & 11 deletions cadence/contracts/bridge/FlowEVMBridge.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import "FlowToken"

import "EVM"

import "EVMUtils"
import "SerializeNFT"
import "BridgePermissions"
import "ICrossVM"
import "IEVMBridgeNFTMinter"
Expand All @@ -21,7 +23,6 @@ import "FlowEVMBridgeUtils"
import "FlowEVMBridgeNFTEscrow"
import "FlowEVMBridgeTokenEscrow"
import "FlowEVMBridgeTemplates"
import "SerializeNFT"

/// The FlowEVMBridge contract is the main entrypoint for bridging NFT & FT assets between Flow & FlowEVM.
///
Expand Down Expand Up @@ -140,7 +141,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
emit Onboarded(
type: type,
cadenceContractAddress: FlowEVMBridgeUtils.getContractAddress(fromType: type)!,
evmContractAddress: FlowEVMBridgeUtils.getEVMAddressAsHexString(address: onboardingValues.evmContractAddress)
evmContractAddress: EVMUtils.getEVMAddressAsHexString(address: onboardingValues.evmContractAddress)
)
}

Expand Down Expand Up @@ -581,14 +582,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
if !FlowEVMBridgeUtils.isValidFlowAsset(type: type) {
return nil
}
if type == Type<@FlowToken.Vault>() {
return false
} else if type.isSubtype(of: Type<@{NonFungibleToken.NFT}>()) {
return !FlowEVMBridgeNFTEscrow.isInitialized(forType: type)
} else if type.isSubtype(of: Type<@{FungibleToken.Vault}>()) {
return !FlowEVMBridgeTokenEscrow.isInitialized(forType: type)
}
return nil
return FlowEVMBridgeConfig.getEVMAddressAssociated(with: type) == nil
}

/// Returns whether an EVM-native asset needs to be onboarded to the bridge
Expand Down Expand Up @@ -812,7 +806,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
assetName: name,
symbol: symbol,
isERC721: isERC721,
evmContractAddress: FlowEVMBridgeUtils.getEVMAddressAsHexString(address: evmContractAddress)
evmContractAddress: EVMUtils.getEVMAddressAsHexString(address: evmContractAddress)
)
}
}
5 changes: 5 additions & 0 deletions cadence/contracts/bridge/FlowEVMBridgeConfig.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ contract FlowEVMBridgeConfig {
/// Mapping of Type to its associated EVMAddress as relevant to the bridge
access(self)
let typeToEVMAddress: {Type: EVM.EVMAddress}
access(self)
let evmAddressHexToType: {String: Type}

/* --- Path Constants --- */
//
Expand Down Expand Up @@ -60,6 +62,7 @@ contract FlowEVMBridgeConfig {
access(account)
fun associateType(_ type: Type, with evmAddress: EVM.EVMAddress) {
self.typeToEVMAddress[type] = evmAddress

}

/*****************
Expand Down Expand Up @@ -100,11 +103,13 @@ contract FlowEVMBridgeConfig {
self.onboardFee = 0.0
self.baseFee = 0.0
self.defaultDecimals = 18

self.typeToEVMAddress = {
Type<@FlowToken.Vault>(): EVM.EVMAddress(
bytes: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
)
}
self.evmAddressHexToType = {}
self.adminStoragePath = /storage/flowEVMBridgeConfigAdmin
self.coaStoragePath = /storage/evm
self.providerCapabilityStoragePath = /storage/bridgeFlowVaultProvider
Expand Down
51 changes: 3 additions & 48 deletions cadence/contracts/bridge/FlowEVMBridgeUtils.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import "FlowStorageFees"

import "EVM"

import "EVMUtils"
import "FlowEVMBridgeConfig"
import "BridgePermissions"

Expand All @@ -29,52 +30,6 @@ contract FlowEVMBridgeUtils {
Public Bridge Utils
**************************/

/// Returns an EVMAddress as a hex string without a 0x prefix
///
/// @param address: The EVMAddress to convert to a hex string
///
/// @return The hex string representation of the EVMAddress without 0x prefix
///
// TODO: Remove once EVMAddress.toString() is available
access(all)
view fun getEVMAddressAsHexString(address: EVM.EVMAddress): String {
let bytes = address.bytes
// Iterating & appending to an array is not allowed in a `view` method and this method must be `view` for
// certain use cases in the bridge contracts - namely for emitting values in pre- & post-conditions
let addressBytes: [UInt8] = [
bytes[0], bytes[1], bytes[2], bytes[3],
bytes[4], bytes[5], bytes[6], bytes[7],
bytes[8], bytes[9], bytes[10], bytes[11],
bytes[12], bytes[13], bytes[14], bytes[15],
bytes[16], bytes[17], bytes[18], bytes[19]
]
return String.encodeHex(addressBytes)
}

/// Returns an EVMAddress as a hex string without a 0x prefix, truncating the string's last 20 bytes if exceeded
///
/// @param address: The hex string to convert to an EVMAddress without the 0x prefix
///
/// @return The EVMAddress representation of the hex string
///
access(all)
fun getEVMAddressFromHexString(address: String): EVM.EVMAddress? {
if address.length != 40 {
return nil
}
var addressBytes: [UInt8] = address.decodeHex()
if addressBytes.length != 20 {
return nil
}
return EVM.EVMAddress(bytes: [
addressBytes[0], addressBytes[1], addressBytes[2], addressBytes[3],
addressBytes[4], addressBytes[5], addressBytes[6], addressBytes[7],
addressBytes[8], addressBytes[9], addressBytes[10], addressBytes[11],
addressBytes[12], addressBytes[13], addressBytes[14], addressBytes[15],
addressBytes[16], addressBytes[17], addressBytes[18], addressBytes[19]
])
}

/// Calculates the fee bridge fee based on the given storage usage. If includeBase is true, the base fee is included
/// in the resulting calculation.
///
Expand Down Expand Up @@ -529,7 +484,7 @@ contract FlowEVMBridgeUtils {
view fun deriveBridgedNFTContractName(from evmContract: EVM.EVMAddress): String {
return self.contractNamePrefixes[Type<@{NonFungibleToken.NFT}>()]!["bridged"]!
.concat(self.delimiter)
.concat("0x".concat(self.getEVMAddressAsHexString(address: evmContract)))
.concat("0x".concat(EVMUtils.getEVMAddressAsHexString(address: evmContract)))
}

/// Derives the Cadence contract name for a given EVM fungible token of the form
Expand All @@ -543,7 +498,7 @@ contract FlowEVMBridgeUtils {
view fun deriveBridgedTokenContractName(from evmContract: EVM.EVMAddress): String {
return self.contractNamePrefixes[Type<@{FungibleToken.Vault}>()]!["bridged"]!
.concat(self.delimiter)
.concat("0x".concat(self.getEVMAddressAsHexString(address: evmContract)))
.concat("0x".concat(EVMUtils.getEVMAddressAsHexString(address: evmContract)))
}

/****************
Expand Down
10 changes: 5 additions & 5 deletions cadence/contracts/bridge/IFlowEVMNFTBridge.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import "NonFungibleToken"

import "EVM"

import "EVMUtils"
import "FlowEVMBridgeConfig"
import "FlowEVMBridgeUtils"
import "CrossVMNFT"

access(all) contract interface IFlowEVMNFTBridge {
Expand Down Expand Up @@ -69,8 +69,8 @@ access(all) contract interface IFlowEVMNFTBridge {
type: token.getType(),
id: token.id,
evmID: CrossVMNFT.getEVMID(from: &token as &{NonFungibleToken.NFT}) ?? UInt256(token.id),
to: FlowEVMBridgeUtils.getEVMAddressAsHexString(address: to),
evmContractAddress: FlowEVMBridgeUtils.getEVMAddressAsHexString(
to: EVMUtils.getEVMAddressAsHexString(address: to),
evmContractAddress: EVMUtils.getEVMAddressAsHexString(
address: self.getAssociatedEVMAddress(with: token.getType())
?? panic("Could not find EVM Contract address associated with provided NFT")
), bridgeAddress: self.account.address
Expand Down Expand Up @@ -104,8 +104,8 @@ access(all) contract interface IFlowEVMNFTBridge {
type: result.getType(),
id: result.id,
evmID: id,
caller: FlowEVMBridgeUtils.getEVMAddressAsHexString(address: owner),
evmContractAddress: FlowEVMBridgeUtils.getEVMAddressAsHexString(
caller: EVMUtils.getEVMAddressAsHexString(address: owner),
evmContractAddress: EVMUtils.getEVMAddressAsHexString(
address: self.getAssociatedEVMAddress(with: result.getType())
?? panic("Could not find EVM Contract address associated with provided NFT")
), bridgeAddress: self.account.address
Expand Down
10 changes: 5 additions & 5 deletions cadence/contracts/bridge/IFlowEVMTokenBridge.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import "NonFungibleToken"

import "EVM"

import "FlowEVMBridgeUtils"
import "EVMUtils"

access(all) contract interface IFlowEVMTokenBridge {

Expand Down Expand Up @@ -64,8 +64,8 @@ access(all) contract interface IFlowEVMTokenBridge {
emit BridgedTokensToEVM(
type: vault.getType(),
amount: vault.balance,
to: FlowEVMBridgeUtils.getEVMAddressAsHexString(address: to),
evmContractAddress: FlowEVMBridgeUtils.getEVMAddressAsHexString(
to: EVMUtils.getEVMAddressAsHexString(address: to),
evmContractAddress: EVMUtils.getEVMAddressAsHexString(
address: self.getAssociatedEVMAddress(with: vault.getType())
?? panic("Could not find EVM Contract address associated with provided NFT")
), bridgeAddress: self.account.address
Expand Down Expand Up @@ -98,8 +98,8 @@ access(all) contract interface IFlowEVMTokenBridge {
emit BridgedTokensFromEVM(
type: result.getType(),
amount: amount,
caller: FlowEVMBridgeUtils.getEVMAddressAsHexString(address: owner),
evmContractAddress: FlowEVMBridgeUtils.getEVMAddressAsHexString(
caller: EVMUtils.getEVMAddressAsHexString(address: owner),
evmContractAddress: EVMUtils.getEVMAddressAsHexString(
address: self.getAssociatedEVMAddress(with: result.getType())
?? panic("Could not find EVM Contract address associated with provided Vault")
), bridgeAddress: self.account.address
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import "FlowEVMBridgeUtils"
import "EVMUtils"
import "FlowEVMBridge"

/// Returns whether a EVM contract needs to be onboarded to the FlowEVMBridge
Expand All @@ -15,7 +15,7 @@ access(all) fun main(evmAddresses: [String]): {String: Bool?} {
if results[addressHex] != nil {
continue
}
if let address = FlowEVMBridgeUtils.getEVMAddressFromHexString(address: addressHex) {
if let address = EVMUtils.getEVMAddressFromHexString(address: addressHex) {
let requiresOnboarding = FlowEVMBridge.evmAddressRequiresOnboarding(address)
results.insert(key: addressHex, requiresOnboarding)
}
Expand Down
4 changes: 2 additions & 2 deletions cadence/scripts/bridge/evm_address_requires_onboarding.cdc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import "FlowEVMBridgeUtils"
import "EVMUtils"
import "FlowEVMBridge"

/// Returns whether a EVM contract needs to be onboarded to the FlowEVMBridge
Expand All @@ -8,7 +8,7 @@ import "FlowEVMBridge"
/// @return Whether the contract requires onboarding to the FlowEVMBridge if the type is bridgeable, otherwise nil
///
access(all) fun main(evmAddressHex: String): Bool? {
if let address = FlowEVMBridgeUtils.getEVMAddressFromHexString(address: evmAddressHex) {
if let address = EVMUtils.getEVMAddressFromHexString(address: evmAddressHex) {
return FlowEVMBridge.evmAddressRequiresOnboarding(address)
}
return nil
Expand Down
4 changes: 2 additions & 2 deletions cadence/scripts/bridge/get_associated_evm_address.cdc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "EVM"

import "EVMUtils"
import "FlowEVMBridgeConfig"
import "FlowEVMBridgeUtils"

/// Returns the EVM address associated with the given Cadence type (as its identifier String)
///
Expand All @@ -13,7 +13,7 @@ access(all)
fun main(identifier: String): String? {
if let type = CompositeType(identifier) {
if let address = FlowEVMBridgeConfig.getEVMAddressAssociated(with: type) {
return FlowEVMBridgeUtils.getEVMAddressAsHexString(address: address)
return EVMUtils.getEVMAddressAsHexString(address: address)
}
}
return nil
Expand Down
4 changes: 2 additions & 2 deletions cadence/scripts/bridge/get_bridge_coa_address.cdc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "EVM"

import "FlowEVMBridgeUtils"
import "EVMUtils"
import "FlowEVMBridge"

/// Returns the EVM address associated with the FlowEVMBridge
Expand All @@ -9,5 +9,5 @@ import "FlowEVMBridge"
///
access(all) fun main(): String {
let address: EVM.EVMAddress = FlowEVMBridge.getBridgeCOAEVMAddress()
return FlowEVMBridgeUtils.getEVMAddressAsHexString(address: address)
return EVMUtils.getEVMAddressAsHexString(address: address)
}
4 changes: 2 additions & 2 deletions cadence/scripts/evm/get_evm_address_string_from_bytes.cdc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "EVM"

import "FlowEVMBridgeUtils"
import "EVMUtils"

/// Converts EVM address bytes into to a hex string
///
Expand All @@ -13,5 +13,5 @@ access(all) fun main(bytes: [UInt8]): String? {
bytes[15], bytes[16], bytes[17], bytes[18], bytes[19]
]
)
return FlowEVMBridgeUtils.getEVMAddressAsHexString(address: address)
return EVMUtils.getEVMAddressAsHexString(address: address)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import "EVM"

import "EVMDeployer"

import "FlowEVMBridgeUtils"
import "EVMUtils"

access(all)
fun main(name: String): String {
return FlowEVMBridgeUtils.getEVMAddressAsHexString(
return EVMUtils.getEVMAddressAsHexString(
address: EVMDeployer.deployedAddresses[name] ?? panic("Could not find deployed address for: ".concat(name))
)
}
4 changes: 2 additions & 2 deletions cadence/scripts/test/get_deployed_contract_address_string.cdc
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import "EVM"

import "FlowEVMBridgeUtils"
import "EVMUtils"

import "EVMDeployer"

access(all) fun main(): String {
return FlowEVMBridgeUtils.getEVMAddressAsHexString(address: EVMDeployer.deployedContractAddress)
return EVMUtils.getEVMAddressAsHexString(address: EVMDeployer.deployedContractAddress)
}
5 changes: 3 additions & 2 deletions cadence/scripts/utils/balance_of.cdc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "EVM"

import "EVMUtils"
import "FlowEVMBridgeUtils"

/// Returns the balance of the owner (hex-encoded EVM address - minus 0x prefix) of a given ERC20 fungible token defined
Expand All @@ -13,9 +14,9 @@ import "FlowEVMBridgeUtils"
///
access(all) fun main(owner: String, evmContractAddress: String): UInt256 {
return FlowEVMBridgeUtils.balanceOf(
owner: FlowEVMBridgeUtils.getEVMAddressFromHexString(address: owner)
owner: EVMUtils.getEVMAddressFromHexString(address: owner)
?? panic("Invalid owner address"),
evmContractAddress: FlowEVMBridgeUtils.getEVMAddressFromHexString(address: evmContractAddress)
evmContractAddress: EVMUtils.getEVMAddressFromHexString(address: evmContractAddress)
?? panic("Invalid EVM contract address")
)
}
3 changes: 2 additions & 1 deletion cadence/scripts/utils/derive_bridged_nft_contract_name.cdc
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import "EVM"

import "EVMUtils"
import "FlowEVMBridgeUtils"

access(all)
fun main(evmAddressHex: String): String {
return FlowEVMBridgeUtils.deriveBridgedNFTContractName(
from: FlowEVMBridgeUtils.getEVMAddressFromHexString(address: evmAddressHex) ?? panic("Could not parse EVM address from hex string")
from: EVMUtils.getEVMAddressFromHexString(address: evmAddressHex) ?? panic("Could not parse EVM address from hex string")
)
}
3 changes: 2 additions & 1 deletion cadence/scripts/utils/derive_bridged_token_contract_name.cdc
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import "EVM"

import "EVMUtils"
import "FlowEVMBridgeUtils"

access(all)
fun main(evmAddressHex: String): String {
return FlowEVMBridgeUtils.deriveBridgedTokenContractName(
from: FlowEVMBridgeUtils.getEVMAddressFromHexString(address: evmAddressHex) ?? panic("Could not parse EVM address from hex string")
from: EVMUtils.getEVMAddressFromHexString(address: evmAddressHex) ?? panic("Could not parse EVM address from hex string")
)
}
4 changes: 3 additions & 1 deletion cadence/scripts/utils/get_factory_address.cdc
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import "EVM"

import "EVMUtils"

import "FlowEVMBridgeUtils"

/// Returns the EVM address of the FlowEVMBridgeFactory solidity contract
///
/// @return The EVM address of the FlowEVMBridgeFactory contract as hex string (without 0x prefix)
///
access(all) fun main(): String {
return FlowEVMBridgeUtils.getEVMAddressAsHexString(address: FlowEVMBridgeUtils.bridgeFactoryEVMAddress)
return EVMUtils.getEVMAddressAsHexString(address: FlowEVMBridgeUtils.bridgeFactoryEVMAddress)
}
Loading

0 comments on commit c987f43

Please sign in to comment.