Skip to content

Commit

Permalink
add NFT serialization into bridge to EVM
Browse files Browse the repository at this point in the history
  • Loading branch information
sisyphusSmiling committed Mar 18, 2024
1 parent b8d20e7 commit 1ab17d8
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
2 changes: 1 addition & 1 deletion cadence/args/deploy-factory-args.json

Large diffs are not rendered by default.

34 changes: 25 additions & 9 deletions cadence/contracts/bridge/FlowEVMBridge.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import "FlowEVMBridgeConfig"
import "FlowEVMBridgeUtils"
import "FlowEVMBridgeNFTEscrow"
import "FlowEVMBridgeTemplates"
import "SerializeNFT"

/// The FlowEVMBridge contract is the main entrypoint for bridging NFT & FT assets between Flow & FlowEVM.
///
Expand Down Expand Up @@ -135,11 +136,6 @@ contract FlowEVMBridge : IFlowEVMNFTBridge {
let tokenType = token.getType()
let tokenID = token.id
let evmID = CrossVMNFT.getEVMID(from: &token as &{NonFungibleToken.NFT}) ?? UInt256(token.id)
// Grab the URI from the NFT if available
var uri: String = ""
if let metadata = token.resolveView(Type<CrossVMNFT.EVMBridgedMetadata>()) as! CrossVMNFT.EVMBridgedMetadata? {
uri = metadata.uri.uri()
}

// Lock the NFT & calculate the storage used by the NFT
let storageUsed = FlowEVMBridgeNFTEscrow.lockNFT(<-token)
Expand All @@ -159,6 +155,16 @@ contract FlowEVMBridge : IFlowEVMNFTBridge {
let isFactoryDeployed = FlowEVMBridgeUtils.isEVMContractBridgeOwned(evmContractAddress: associatedAddress)
// Controlled by the bridge - mint or transfer based on existence
if isFactoryDeployed {
// Grab the URI from the NFT if available
var uri: String = ""
// Default to project-specified URI
if let metadata = token.resolveView(Type<CrossVMNFT.EVMBridgedMetadata>()) as! CrossVMNFT.EVMBridgedMetadata? {
uri = metadata.uri.uri()
} else {
// Otherwise, serialize the NFT using OpenSea Metadata strategy
uri = SerializeNFT.serializeNFTMetadataAsURI(&token as &{NonFungibleToken.NFT})
}

// Check if the ERC721 exists
let existsResponse = EVM.decodeABI(
types: [Type<Bool>()],
Expand All @@ -173,17 +179,27 @@ contract FlowEVMBridge : IFlowEVMNFTBridge {
assert(existsResponse.length == 1, message: "Invalid response length")
let exists = existsResponse[0] as! Bool
if exists {
// if so transfer
let callResult: EVM.Result = FlowEVMBridgeUtils.call(
// If so transfer
let transferResult: EVM.Result = FlowEVMBridgeUtils.call(
signature: "safeTransferFrom(address,address,uint256)",
targetEVMAddress: associatedAddress,
args: [self.getBridgeCOAEVMAddress(), to, evmID],
gasLimit: 15000000,
value: 0.0
)
assert(callResult.status == EVM.Status.successful, message: "Tranfer to bridge recipient failed")
assert(transferResult.status == EVM.Status.successful, message: "Tranfer to bridge recipient failed")

// And update the URI to reflect current metadata
let updateURIResult: EVM.Result = FlowEVMBridgeUtils.call(
signature: "updateTokenURI(uint256,string)",
targetEVMAddress: associatedAddress,
args: [evmID, uri],
gasLimit: 15000000,
value: 0.0
)
assert(updateURIResult.status == EVM.Status.successful, message: "Tranfer to bridge recipient failed")
} else {
// Otherwise mint
// Otherwise mint with current URI
let callResult: EVM.Result = FlowEVMBridgeUtils.call(
signature: "safeMint(address,uint256,string)",
targetEVMAddress: associatedAddress,
Expand Down
4 changes: 4 additions & 0 deletions solidity/src/FlowBridgedERC721.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ contract FlowBridgedERC721 is ERC721, ERC721URIStorage, ERC721Burnable, ERC721En
_setTokenURI(tokenId, uri);
}

function updateTokenURI(uint256 tokenId, string memory uri) public onlyOwner {
_setTokenURI(tokenId, uri);
}

function contractURI() public view returns (string memory) {
return contractMetadata;
}
Expand Down

0 comments on commit 1ab17d8

Please sign in to comment.