Links

CrossChainBridgeERC721

Manages deposits and releases for ERC721 bridge transactions

Functions

deposit

Accepts ERC721 deposits that should be bridged into another network (effectively starting a bridge transaction). The collection must be whitelisted in order to be accepted for a deposit.
function deposit(
address collectionAddress,
uint256 tokenId,
address receiverAddress,
uint256 targetChainId
) external payable whenNotPaused {
// check if token was minted from an original collection or minted by this bridge
if (mintedDeposits[collectionAddress][tokenId]) {
// no whitelist check necessary since token was minted by this bridge
MintableERC721(collectionAddress).burn(tokenId);
} else {
if (!officialCollectionWhitelist[collectionAddress]) revert Unauthorized();
// transfer the token into the bridge
IERC721Upgradeable(collectionAddress).safeTransferFrom(_msgSender(), address(this), tokenId);
}
// For every deposit we increase the counter to create a unique ID that can be used on the target side bridge to avoid double releases
depositCount = depositCount + 1;
// We always dispatch the deposit event with the "true" token address in the source network
emit TokenDeposited(collectionAddress, tokenId, receiverAddress, _getChainID(), targetChainId, depositCount);
}

Parameters:

Name
Type
Description
collectionAddress
address
the address of the ERC721 contract the collection was issued with
tokenId
uint256
the (native) ID of the ERC721 token that should be bridged
receiverAddress
address
the address which should receive the bridged token in the target network
targetChainId
uint256
chain ID of the target network

release

Releases an ERC721 token in this network after a deposit was made in the source network (effectively completing a bridge transaction)
function release(
uint8[] memory sigV,
bytes32[] memory sigR,
bytes32[] memory sigS,
address receiverAddress,
address sourceNetworkCollectionAddress,
uint256 tokenId,
uint256 depositChainId,
uint256 depositNumber
) external payable whenNotPaused {
// check input parameters
if (releasedDeposits[depositChainId][depositNumber]) revert AlreadyUsed();
if (
!multiSignatureOracle.signaturesCheckERC721(
sigV,
sigR,
sigS,
receiverAddress,
sourceNetworkCollectionAddress,
tokenId,
depositChainId,
depositNumber
)
) revert Unauthorized();
// get collection address in release network
address collectionAddress = sourceNetworkCollectionAddress;
if (outsidePeggedCollections[collectionAddress] != address(0)) {
collectionAddress = outsidePeggedCollections[collectionAddress];
}
// calculate bridging fee
uint256 nftBridgingFee = defaultBridgeFee;
if (bridgeFees[collectionAddress] > 0) {
nftBridgingFee = bridgeFees[collectionAddress];
}
// check if transaction contains enough native tokens to pay the bridging fee
if (msg.value < nftBridgingFee) revert InvalidMessageValue(msg.value, nftBridgingFee);
// check if to-be-released token is part of the official collection (whitelisted)
if (officialCollectionWhitelist[collectionAddress] == true) {
ERC721Upgradeable(collectionAddress).safeTransferFrom(address(this), receiverAddress, tokenId);
} else {
MintableERC721(collectionAddress).mint(receiverAddress, tokenId);
mintedDeposits[collectionAddress][tokenId] = true;
}
// update records to track released deposits
releasedDeposits[depositChainId][depositNumber] = true;
// release successful, deposit event
emit TokenReleased(collectionAddress, tokenId, receiverAddress, depositChainId, depositNumber);
}

Parameters:

Name
Type
Description
sigV
uint8
Array of recovery Ids for the signature
sigR
bytes32
Array of R values of the signatures
sigS
bytes32
Array of S values of the signatures
receiverAddress
address
the address to which the bridged token should be released to
sourceNetworkCollectionAddress
address
the address of the ERC721 collection in the network in which the deposit was made
tokenId
uint256
The tokenId to be released
depositChainId
uint256
chain ID of the network in which the deposit was made
depositNumber
uint256
The deposit ID of the corresponding deposit