# 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:
- Emerald Mainnet - 0xF871be292Dc9265F86A56b34502845E062888d0c (opens new window)
- Emerald Testnet - 0x0cF5B8097F5bA0F7610895CEc799D5b975AECf37 (opens new window)
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
- ERC165 (opens new window)
- ERC721TokenReceiver (opens new window)
- ERC1155TokenReceiver (opens new window)
- ERC1363Receiver (opens new window)
# 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
.