Skip to content

Commit

Permalink
update contract comments
Browse files Browse the repository at this point in the history
  • Loading branch information
sisyphusSmiling committed Apr 24, 2024
1 parent b3688e3 commit e008d1e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 28 deletions.
55 changes: 31 additions & 24 deletions cadence/contracts/bridge/FlowEVMBridge.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,24 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
pre {
type != Type<@FlowToken.Vault>():
"$FLOW cannot be bridged via the VM bridge - use the CadenceOwnedAccount interface"
feeProvider.isAvailableToWithdraw(amount: FlowEVMBridgeConfig.onboardFee):
"Insufficient fee available via feeProvider"
self.typeRequiresOnboarding(type) == true: "Onboarding is not needed for this type"
FlowEVMBridgeUtils.typeAllowsBridging(type):
"This type is not supported as defined by the project's development team"
FlowEVMBridgeUtils.isCadenceNative(type: type): "Only Cadence-native assets can be onboarded by Type"
}
// Ensure the project has not opted out of bridge support
assert(
FlowEVMBridgeUtils.typeAllowsBridging(type),
message: "This type is not supported as defined by the project's development team"
)
/* Provision fees */
//
// Withdraw from feeProvider and deposit to self
FlowEVMBridgeUtils.depositFee(feeProvider, feeAmount: FlowEVMBridgeConfig.onboardFee)

/* EVM setup */
//
// Deploy an EVM defining contract via the FlowBridgeFactory.sol contract
let onboardingValues = self.deployEVMContract(forAssetType: type)
// Initialize bridge escrow for the asset

/* Cadence escrow setup */
//
// Initialize bridge escrow for the asset based on its type
if type.isSubtype(of: Type<@{NonFungibleToken.NFT}>()) {
FlowEVMBridgeNFTEscrow.initializeEscrow(
forType: type,
Expand All @@ -133,6 +136,8 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
panic("Attempted to onboard unsupported type: ".concat(type.identifier))
}

/* Confirmation */
//
assert(
FlowEVMBridgeNFTEscrow.isInitialized(forType: type) || FlowEVMBridgeTokenEscrow.isInitialized(forType: type),
message: "Failed to initialize escrow for given type"
Expand All @@ -157,10 +162,8 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
_ address: EVM.EVMAddress,
feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}
) {
pre {
feeProvider.isAvailableToWithdraw(amount: FlowEVMBridgeConfig.onboardFee):
"Insufficient fee available via feeProvider"
}
/* Validate the EVM contract */
//
// Ensure the project has not opted out of bridge support
assert(
FlowEVMBridgeUtils.evmAddressAllowsBridging(address),
Expand All @@ -170,17 +173,23 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
self.evmAddressRequiresOnboarding(address) == true,
message: "Onboarding is not needed for this contract"
)

/* Provision fees */
//
// Withdraw fee from feeProvider and deposit
FlowEVMBridgeUtils.depositFee(feeProvider, feeAmount: FlowEVMBridgeConfig.onboardFee)

/* Setup Cadence-defining contract */
//
// Deploy a defining Cadence contract to the bridge account
self.deployDefiningContract(evmContractAddress: address)
}

/*************************
Public NFT Handling
NFT Handling
**************************/

/// Public entrypoint to bridge NFTs from Cadence to EVM.
/// Public entrypoint to bridge NFTs from Cadence to EVM as ERC721.
///
/// @param token: The NFT to be bridged
/// @param to: The NFT recipient in FlowEVM
Expand Down Expand Up @@ -281,7 +290,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
}
}

/// Public entrypoint to bridge NFTs from EVM to Cadence
/// Entrypoint to bridge ERC721 from EVM to Cadence as NonFungibleToken.NFT
///
/// @param owner: The EVM address of the NFT owner. Current ownership and successful transfer (via
/// `protectedTransferCall`) is validated before the bridge request is executed.
Expand All @@ -303,8 +312,6 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
protectedTransferCall: fun (): EVM.Result
): @{NonFungibleToken.NFT} {
pre {
feeProvider.isAvailableToWithdraw(amount: FlowEVMBridgeUtils.calculateBridgeFee(bytes: 0)):
"Insufficient fee paid"
!type.isSubtype(of: Type<@{FungibleToken.Vault}>()): "Mixed asset types are not yet supported"
self.typeRequiresOnboarding(type) == false: "NFT must first be onboarded"
}
Expand Down Expand Up @@ -361,10 +368,10 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
}

/**************************
Public FT Handling
FT Handling
***************************/

/// Public entrypoint to bridge FTs from Cadence to EVM.
/// Public entrypoint to bridge FTs from Cadence to EVM as ERC20 tokens.
///
/// @param vault: The fungible token Vault to be bridged
/// @param to: The fungible token recipient in EVM
Expand Down Expand Up @@ -433,8 +440,10 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
let associatedAddress = FlowEVMBridgeConfig.getEVMAddressAssociated(with: vaultType)
?? panic("No EVMAddress found for vault type")
// Convert the vault balance to a UInt256
let decimals = FlowEVMBridgeUtils.getTokenDecimals(evmContractAddress: associatedAddress)
let bridgeAmount = FlowEVMBridgeUtils.ufix64ToUInt256(value: vaultBalance, decimals: decimals)
let bridgeAmount = FlowEVMBridgeUtils.convertCadenceAmountToERC20Amount(
vaultBalance,
erc20Address: associatedAddress
)
// Determine if the EVM contract is bridge-owned - affects how tokens are transmitted to recipient
let isFactoryDeployed = FlowEVMBridgeUtils.isEVMContractBridgeOwned(evmContractAddress: associatedAddress)

Expand All @@ -448,7 +457,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
}
}

/// Public entrypoint to bridge FTs from EVM to Cadence
/// Entrypoint to bridge ERC20 tokens from EVM to Cadence as FungibleToken Vaults
///
/// @param owner: The EVM address of the FT owner. Current ownership and successful transfer (via
/// `protectedTransferCall`) is validated before the bridge request is executed.
Expand All @@ -470,8 +479,6 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
protectedTransferCall: fun (): EVM.Result
): @{FungibleToken.Vault} {
pre {
feeProvider.isAvailableToWithdraw(amount: FlowEVMBridgeUtils.calculateBridgeFee(bytes: 0)):
"Insufficient fee paid"
!type.isSubtype(of: Type<@{NonFungibleToken.Collection}>()): "Mixed asset types are not yet supported"
!type.isInstance(Type<@FlowToken.Vault>()): "Must use the CadenceOwnedAccount interface to bridge $FLOW from EVM"
self.typeRequiresOnboarding(type) == false: "NFT must first be onboarded"
Expand Down
5 changes: 1 addition & 4 deletions cadence/contracts/bridge/FlowEVMBridgeHandlers.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,7 @@ access(all) contract FlowEVMBridgeHandlers {

// Get values from vault and burn
let amount = tokens.balance
let uintAmount = FlowEVMBridgeUtils.ufix64ToUInt256(
value: amount,
decimals: FlowEVMBridgeUtils.getTokenDecimals(evmContractAddress: evmAddress)
)
let uintAmount = FlowEVMBridgeUtils.convertCadenceAmountToERC20Amount(amount, erc20Address: evmAddress)

Burner.burn(<-tokens)

Expand Down
30 changes: 30 additions & 0 deletions cadence/contracts/bridge/FlowEVMBridgeUtils.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,14 @@ contract FlowEVMBridgeUtils {
return decodedResult[0] as! UInt256
}

/// Converts the given amount of ERC20 tokens to the equivalent amount in FLOW tokens based on the ERC20s decimals
/// value. Reverts on EVM call failure.
///
/// @param amount: The amount of ERC20 tokens to convert
/// @param erc20Address: The EVM contract address of the ERC20 token
///
/// @return the equivalent amount in FLOW tokens as a UFix64
///
access(all)
fun convertERC20AmountToCadenceAmount(_ amount: UInt256, erc20Address: EVM.EVMAddress): UFix64 {
return self.uint256ToUFix64(
Expand All @@ -474,6 +482,19 @@ contract FlowEVMBridgeUtils {
)
}

/// Converts the given amount of Cadence fungible tokens to the equivalent amount in ERC20 tokens based on the
/// ERC20s decimals. Reverts on EVM call failure.
///
/// @param amount: The amount of Cadence fungible tokens to convert
/// @param erc20Address: The EVM contract address of the ERC20 token
///
/// @return the equivalent amount in ERC20 tokens as a UInt256
///
access(all)
fun convertCadenceAmountToERC20Amount(_ amount: UFix64, erc20Address: EVM.EVMAddress): UInt256 {
return self.ufix64ToUInt256(value: amount, decimals: self.getTokenDecimals(evmContractAddress: erc20Address))
}

/************************
Derivation Utils
************************/
Expand Down Expand Up @@ -735,6 +756,8 @@ contract FlowEVMBridgeUtils {
)
}

/// Mints ERC20 tokens to the recipient and confirms that the recipient's balance was updated
///
access(account)
fun mustMintERC20(to: EVM.EVMAddress, amount: UInt256, erc20Address: EVM.EVMAddress) {
let toPreBalance = FlowEVMBridgeUtils.balanceOf(owner: to, evmContractAddress: erc20Address)
Expand All @@ -755,6 +778,9 @@ contract FlowEVMBridgeUtils {
)
}

/// Transfers ERC20 tokens to the recipient and confirms that the recipient's balance was incremented and the escrow
/// balance was decremented by the requested amount.
///
access(account)
fun mustTransferERC20(to: EVM.EVMAddress, amount: UInt256, erc20Address: EVM.EVMAddress) {
let bridgeCOAAddress = self.getBridgeCOAEVMAddress()
Expand Down Expand Up @@ -791,6 +817,10 @@ contract FlowEVMBridgeUtils {
)
}

/// Executes the provided method, assumed to be a protected transfer call, and confirms that the transfer was
/// successful by validating that the named owner's balance was decremented by the requested amount and the bridge
/// escrow balance was incremented by the same amount.
///
access(account)
fun mustExecuteProtectedERC20TransferCall(
owner: EVM.EVMAddress,
Expand Down

0 comments on commit e008d1e

Please sign in to comment.