This repository contains the smart contracts for the Hedera <-> EVM Bridge.
Core functionality of Hedera <-> EVM Bridge.
In essence, the business logic behind the smart contracts is to allow the possibility to transfer a token from one network to another.
Of course, you cannot directly transfer the token to the network, so in order this to be possible it has to have a representation of that token, a so-called wrapped version of the original native token.
In our terms, a wrapped token on a given network is a representation of a native token on another network. A native token can have wrapped representations on more than one EVM network.
Users operate with the following functionality:
lock- lock a specific amount of native tokens, specifying the receiver and target network.unlock- unlock a previously locked amount of native tokens by providing an array of signatures. Signatures are verified that they are signed by themembers.mint- mint a specific amount of wrapped tokens by providing an array of signatures, verified that they are signed by themembers.burn- burn a specific amount of wrapped tokens.
EVM native tokens have to be explicitly added as supported native tokens in the smart contracts.
Each native token has a service fee percentage, which will be left for the smart contract members upon locking/unlocking native tokens.
Members are entities, which will serve as governance whenever a user wants to get wrapped tokens from native tokens and vice versa.
Fees for native tokens accumulate equally between members.
Members need to explicitly claim (transfer) their accumulated fees for a given native token.
You can read more here.
Smart Contracts use EIP-2535.
Facet ABIs are available under ./abi directory.
node.js >= v14.17.0
hardhat - framework used for the development and testing of the contracts
After cloning, run:
cd hedera-eth-bridge-contracts
npm install
Before you deploy the contracts, you will need to compile them using:
npx hardhat compile
Before running any npx hardhat scripts, you need to set the following environment variables
in hardhat config or export them:
export ALCHEMY_PROJECT_ID=<PROJECT ID of ALCHEMY>
export DEPLOYER_PRIVATE_KEY=<private key to use for deployments for the specified network>
- Deploys all the facets
- Deploys the Router Diamond with all the facets as diamond cuts
- Initializes
GovernanceFacetwith the provided list of members, governance percentage, and governance precision - Initializes
RouterFacet - Initializes
FeeCalculatorFacetwith the provided fee precision. - As a second step - the script will update the router as follows:
- Add
PaymentFacet - Add
ERC721PortalFacet - Replace
GovernanceFacetwithGovernanceV2Facet
- Add
npx hardhat deploy-router \
--network <network name> \
--owner <owner address> \
--governance-percentage <governance percentage> \
--governance-precision <governance precision> \
--fee-calculator-precision <fee calculator precision> \
--members <list of members, split by `,`> \
--members-admins <list of members admins, split by `,`>Deploys a wrapped token through Router for a corresponding token on another chain:
npx hardhat deploy-router-wrapped-token \
--network <network name> \
--router <address of the router diamond contract> \
--source <id of the source chain, to which the native token is deployed> \
--native <the unique identifier of the native token> \
--name <name of the wrapped token> \
--symbol <symbol of the wrapped token> \
--decimals <decimals of the wrapped token>Deploys an instance of a Wrapped Token contract, used for testing purposes.
npx hardhat deploy-wrapped-token \
--network <network name> \
--name <name of the token> \
--symbol <symbol of the token> \
--decimals <decimals of the token>Deploys a wrapped ERC-721 and transfers ownership to Diamond Router
npx hardhat deploy-wrapped-erc721-transfer-ownership \
--network <network name> \
--router <address of the router diamond contract> \
--name <name of the ERC-721> \
--symbol <symbol of the ERC-721>Deploys a wrapped ERC-721Pausable and transfers ownership to Diamond Router
npx hardhat deploy-wrapped-erc721-pausable-transfer-ownership \
--network <network name> \
--router <address of the router diamond contract> \
--name <name of the ERC-721> \
--symbol <symbol of the ERC-721>Deploys an instance of a Token contract, used for testing purposes.
npx hardhat deploy-token \
--network <network name> \
--name <name of the token> \
--symbol <symbol of the token> \
--decimals <decimals of the token>Updates a native token to the Router contract:
npx hardhat update-native-token \
--network <network name> \
--router <address of the router diamond contract> \
--native-token <address of the native token> \
--fee-percentage <fee percetange for the given token> \
--status <true|false (default true)>Upgrades the diamond to support ERC-721:
npx hardhat upgrade-erc721-support \
--network <network name> \
--router <address of the Router Diamond contract>Requires Router Diamond Contract to be upgraded with PaymentFacet support
npx hardhat set-payment-token \
--network <network name> \
--router <address of the Router Diamond contract> \
--payment-token <address of ERC-20 payment token contract> \
--status <true|false (default true)>Requires Router Diamond Contract to be upgraded with ERC721PortalFacet & PaymentFacet support
npx hardhat set-erc721-payment \
--network <network name> \
--router <address of the Router Diamond contract> \
--erc721 <address of the ERC-721 contract> \
--payment-token <address of the ERC-20 payment token contract> \
--fee <required Payment Token fee upon burnERC721 wrapped transfers>Requires Router Diamond Contract to support ERC721PortalFacet Mints Wrapped ERC-721 tokenID to the corresponding network
npx hardhat mint-erc721 \
--network <network name> \
--router <address of the Router Diamond contract> \
--source-chain-id <The chain id of the source chain> \
--target-chain-id <The chain id of the target chain> \
--transaction-id <The target transaction id> \
--wrapped-asset <The address of the wrapped ERC-721 token> \
--token-id <The target token ID to be minted> \
--metadata <The token ID metadata> \
--receiver <The address of the receiver> \
--signatures <An array of signatures, split by `,`>Burns Wrapped ERC-721 tokenId to the corresponding network
npx hardhat burn-erc721 \
--network <network name> \
--router <address of the Router Diamond contract> \
--target-chain-id <The chain id of the target chain> \
--wrapped-asset <The address of the wrapped ERC-721 token> \
--token-id <The token id to be burned> \
--receiver <The address/AccountID of the receiver>Mints Wrapped ERC-20 amount to the corresponding network
npx hardhat mint-erc20 \
--network <network name> \
--router <address of the Router Diamond contract> \
--source-chain-id <The chain id of the source chain> \
--target-chain-id <The chain id of the target chain> \
--transaction-id <The target transaction id> \
--wrapped-asset <The address of the wrapped ERC-20 token> \
--receiver <The address of the receiver> \
--amount <The amount to be minted> \
--signatures <An array of signatures, split by `,`>Approves & Burns Wrapped ERC-20 amount to the corresponding network
npx hardhat burn-erc20 \
--network <network name> \
--router <address of the Router Diamond contract> \
--target-chain-id <The chain id of the target chain> \
--wrapped-asset <The address of the wrapped ERC-20 token> \
--amount <The target amount> \
--receiver <The address/AccountID of the receiver on the target network>Locks Native ERC-20 amount to the corresponding network
npx hardhat lock-erc20 \
--network <network name> \
--router <address of the Router Diamond contract> \
--target-chain-id <The chain id of the target chain> \
--native-asset <The address of the native ERC-20 token> \
--amount <The amount to be locked> \
--receiver <The address/AccountID of the receiver>Unlocks Native ERC-20 amount to the corresponding network
npx hardhat unlock-erc20 \
--network <network name> \
--router <address of the Router Diamond contract> \
--source-chain-id <The chain id of the source chain> \
--target-chain-id <The chain id of the target chain> \
--transaction-id <The target transaction id> \
--native-asset <The address of the native ERC-20 token> \
--receiver <The address of the receiver> \
--amount <The amount to be minted> \
--signatures <An array of signatures, split by `,`>Transfers Ownership of a Contract to specified new owner.
npx hardhat transfer-ownership \
--network <network name> \
--contract <address of the contract> \
--new-owner <address of the new owner>npx hardhat testnpx hardhat coverage-
lockWithPermit- Whole balance ~ 70 000 gas
- ~ 82 000 gas
-
unlock- 3 signatures ~ 118 132 gas
- ~ 8500 gas per signature
-
mint- 3 signatures ~ 140 223 gas
- ~ 8500 gas per signature
-
burnWithPermit- Whole balance ~ 45 127 gas
- ~70 322 gas
-
updateMember- Addition
- 3 tokens ~ 180 000 gas (if fees for tokens have been accrued at least once)
- ~ 35 000 gas per Token
- Removal
- 3 tokens ~ 140 000 gas
- ~ 37 000 gas per Token
- Addition
NB! Running Unit Tests includes a gas reporter, providing metrics for method calls and deployments.