# Parcel EVM Bridge Adapter

The Parcel EVM Bridge Adapter is deployed to EVM-compatible remote networks (e.g. Emerald) and accepts tokens from that network for bridging to Parcel.

The bridge is one-way, which means that tokens from the remote network can only be sent to Parcel. Tokens created on Parcel cannot be sent to remote networks (though the Parcel job can mint/send tokens on the remote network, but that's a separate discussion).

The deployed Parcel EVM Bridge Adapters can be found at:

The Parcel EVM Bridge Adapter can be accessed using your favorite Web3 library. The Parcel TypeScript client exports an ethers-compatible helper as EmeraldBridgeAdapterV1 on which you can call connect(signerOrProvider).

# Concepts

# Locking & Unlocking

The Parcel bridge is similar to other bridges in that tokens must be locked into a contract on a source network so that off-chain witnesses can process the event and mint the tokens on the destination chain.

Since the Parcel bridge is one-way, there is no requirement to lock/burn tokens on the Parcel side to unlock the tokens on the remote network. This means that you're always free to unlock your remote tokens (though this will revoke your corresponding Parcel tokens).

# Interfaces

# Credits

Bridge actions (locking & unlocking) are only acknowledged when the requester has sufficient credits. Credits are an abstract unit of account maintained as part of your Parcel service agreement. During the Parcel beta, no credits are required to use the bridge, but you should assume that this will change once Parcel is no longer in beta.

You can allow another account on the remote network to use your credits on your behalf.

# API (V1)

# Events

# TokensLocked

TokensLocked(
  address indexed escrower,
  address indexed token,
  uint256 indexed id,
  uint256 amount
)

This event is emitted when an ERC20, ERC721, or ERC1155 token is locked. ERC20 tokens do not have an id, so that field will be zero. Similarly, ERC721 tokens will always have an amount of one.

# TokensLockedBatch

TokensLockedBatch(
  address indexed escrower,
  address indexed token,
  uint256[] ids,
  uint256[] amounts
)

This event is emitted when a batch of ERC1155 tokens is locked. Otherwise, it's similar to TokensLocked.

# TokensUnlocked, TokensUnlockedBatch

TokensUnlocked(
  address indexed escrower,
  address indexed token,
  uint256 indexed id,
  uint256 amount
)

TokensUnlockedBatch(
  address indexed escrower,
  address indexed token,
  uint256[] ids,
  uint256[] amounts
)

These are the straightforward inverses of the lock events.

# State Variables

# uint256 bridgeFeeBase, uint256 bridgeFeePerId

The base fee is the cost in credits to initiate any lock/unlock event. The per-id fee is the number of credits deduced for each token ID transferred. For non-batch transfers, the fee is bridgeFeeBase + bridgeFeePerId. For batch transfers, the fee is bridgeFeePerId + bridgeFeePerId * ids.length.

# bool allowLargeTokenId, bool allowLargeAmount

For efficiency in the (overwhelmingly) common case, Parcel only supports 63-bit token ids and token amounts. As long as these variables remain false, the bridge adapter will reject requests that have larger valued token ids or amounts, respectively. As a consequence, for your token to be bridgable, it must use 63-bit token ids and amounts. If you need larger, please reach out and we'll see what we can do to enable these flags.

# Functions

# Getting and Setting Credit Allowances

# getCredits(address) view returns (uint256)

getCredits(address account) view returns (uint256)

Returns the number of credits held by account. This is a convenience view function for the credits state variable.

# allowCredits(address,uint256)

allowCredits(address operator, uint256 amount)

Permits operator to use up to amount of credits on behalf of the caller. The allowance can be adjusted downward, and can exceed the available number of credits.

# getCreditAllowance(address,address) view returns (uint256)

getCreditAllowance(address operator, address escrower) returns (uint256a)

Returns the remaining credit allowance of operator on behalf of escrower. This is a convenience view function for the creditAllowances state variable.

# Locking

# Locking ERC20

receiveERC20(address escrower, address token, uint256 amount) returns (bool)

Receives ERC20 tokens from a contract whence the escrower has approved at least amount of tokens. Calling this method will call ERC20.transferFrom(escrower, amount) on the token contract, so be sure to call ERC20.approve(bridgeAdapterAddress, amount) before receiving them into the bridge.

Returns true unless reverting.

# Locking ERC1363

onTransferReceived(
  address operator,
  address escrower,
  uint256 amount,
  bytes
) returns (bytes4)

ERC1363 is a souped up ERC20 token that, among other things, notifies a transfer recipient when receiving tokens via the onTransferReceived method. Thus, locking ERC1363 tokens is as simple as transferring to the bridge adapter.

# Locking ERC721

onERC721Received(
  address operator,
  address escrower,
  uint256 id,
  bytes
) returns (bytes4)

This method is called by a compliant ERC721 contract when transferring tokens to the bridge adapter. Thus, locking ERC721 tokens is as simple as transferring to the bridge adapter using ERC721.safeTransferFrom(escrower, bridge, id).

# Locking ERC1155

function onERC1155Received(
  address operator,
  address escrower,
  uint256 id,
  uint256 amount,
  bytes
) returns (bytes4) {
function onERC1155BatchReceived(
  address operator,
  address escrower,
  uint256[] ids,
  uint256[] amounts,
  bytes
) returns (bytes4) {

Like onERC721Received, these two methods are called when a (batch of) ERC1155 token is transferred to the bridge using ERC1155.safeTransferFrom(escrower, bridge, id, amount) or ERC1155.safeBatchTransferFrom(escrower, bridge, ids, amounts).

# Unlocking

The following methods return a token held in escrow back to the caller. The Parcel bridge will revoke access to the Parcel-side tokens.

All return true unless reverting.

# Unlocking ERC20/ERC1363

unlockERC20(address escrower, address token, uint256 amount) returns (bool)

# Unlocking ERC721

unlockERC721(address escrower, address token, uint256 id, bytes data) returns (bool)

data is forwarded to the ERC721 contract via ERC721.safeTransferFrom.

# Unlocking ERC1155

unlockERC1155(
  address escrower,
  address token,
  uint256 id,
  uint256 amount,
  bytes data
) returns (bool)

data is forwarded to the ERC1155 contract via ERC1155.safeTransferFrom.

unlockERC1155Batch(
  address escrower,
  address token,
  uint256[] ids,
  uint256[] amount,
  bytes data
) returns (bool)

data is forwarded to the ERC1155 contract via ERC1155.safeBatchTransferFrom.