Skip to content

Commit

Permalink
Merge pull request #66 from 0xPolygon/readme
Browse files Browse the repository at this point in the history
Readme
  • Loading branch information
wschwab authored Jul 21, 2023
2 parents d79698e + 37840e7 commit 296ac8d
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 37 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,5 @@ jobs:
run: forge build
- name: Slither
uses: crytic/[email protected]
with:
slither-version: "0.9.3"
100 changes: 79 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,60 @@
# fx-portal(Flexible portal)
# FX-Portal (Flexible Portal)

FxPortal for Polygon(prev Matic)Chain. No mapping. Seamless communication with Ethereum Network.
FxPortal for Polygon (prev Matic) Chain. No mappings. Seamless communication with the Ethereum Network.

### Audits

- [Halborn](audits/Polygon_FX_Portal_Smart_Contract_Security_Audit_Halborn_v1_0.pdf)
- [ChainSecurity](audits/ChainSecurity_Polygon_Fx_Portal_audit.pdf)

### What is Fx bridge (fx-portal)?
### Contents

- [What is FX-Portal](#what-is-fx-portal)
- [Some usecases](#some-usecases-of-fx-portal)
- [What about POS-Portal](#what-about-pos-portal)
- [Can I Build My Own Custom Bridge](#can-i-build-my-own-custom-bridge)
- [What Can I Build With FX-Portal](#what-can-i-build-with-fx-portal)
- [What are fxChild and fxRoot](#what-are-fxchild-and-fxroot)
- [Deployment Addresses](#deployment-addresses)
- [Development](#development)
- [Proof Generation](#proof-generation)
- [Future Plans](#future-plans)

### What is FX-Portal?

**A powerful yet simple implementation of Polygon's [state sync](https://wiki.polygon.technology/docs/category/state-sync/) mechanism. (The Polygon [POS-Portal bridge](https://github.com/maticnetwork/pos-portal/) is also based on it, but relies on a centralized party mapping tokens on one chain to their contract on the other.) There are examples of how to use the bridge in the `contracts/examples` directory. You can use these examples to build your own implementations or own custom bridge.**

**It is a powerful yet simple implementation Polygon [state sync](https://docs.matic.network/docs/contribute/state-sync) mechanism. Polygon PoS bridge is based on it. The code in the `examples` folder are examples of the usage of this methodology. You can use these examples to build your own implementations or own custom bridge.**
In short, this bridge allows arbitrary message bridging without mapping, with built-in support for a number of token standards.

In short, it's Meta bridge. This bridge allows any state-syncs without mapping.
In more detail, FX-Portal makes use of a message passing mechanism built into the Polygon POS chain, leveraging it to pass messages from one chain to another. Using a mechanism for generating deterministic token addresses, this can be used to create asset bridges without the need for a centralized party documenting the relationship between assets on the two chains (commonly referred to as a 'mapping' here).

#### Some use-cases of Fx-portal
#### Some usecases of FX-Portal

- [ERC20 token tranfer from Ethereum to Matic-Chain without mapping request](https://github.com/jdkanani/fx-portal/tree/main/contracts/examples/erc20-transfer)
- [Lazy minting of ERC20 tokens on MaticChain](https://github.com/jdkanani/fx-portal/tree/main/contracts/examples/mintable-erc20-transfer)
- [State Transfer between Ethereum-Matic](https://github.com/jdkanani/fx-portal/tree/main/contracts/examples/state-transfer)
- [ERC20 token tranfer from Ethereum to Polygon POS without mapping request](https://github.com/0xPolygon/fx-portal/tree/main/contracts/examples/erc20-transfer)
- [Lazy minting of ERC20 tokens on Polygon POS](https://github.com/0xPolygon/fx-portal/tree/main/contracts/examples/mintable-erc20-transfer)
- [State Transfer between Ethereum mainnet and Polygon POS](https://github.com/0xPolygon/fx-portal/tree/main/contracts/examples/state-transfer)

**What about [PoS portal](https://docs.matic.network/docs/develop/ethereum-matic/pos/getting-started)?**
#### What about [POS-Portal](https://github.com/maticnetwork/pos-portal/)?

PoS Portal is another bridge, but it works only for few ERC standards and requires mappings. It is more developer-friendly, allows customization without much headache.
POS-Portal is another bridge, but it works only for few ERC standards and requires mappings. It is more developer-friendly in some ways, and allows customization without much headache.

While Fx-portal focuses on permissionless-ness and flexibility, a developer might have to write more code but more customizable than PoS Portal. It requires no mapping.
While FX-Portal focuses on permissionlessness and flexibility, a developer might have to write more code than POS-Portal. On the other hand, FX-Portal requires no mapping, meaning that there is no need to rely on an authorized party to submit the mapping with FX-Portal.

**Can I build my bridge?**
#### Can I build my own custom bridge?

Yes. You can check docs here: https://wiki.polygon.technology/docs/develop/l1-l2-communication/ethereum-to-matic/
https://wiki.polygon.technology/docs/develop/l1-l2-communication/matic-to-ethereum/
Yes. You can check docs here: https://wiki.polygon.technology/docs/pos/design/bridge/l1-l2-communication/fx-portal/

### What can I build with FX-Portal?

- Arbitrary state bridge (examples/state-transfer)
- Normal ERC20 bridge (examples/erc2-transfer)
- ERC20 token generator bridge (example/mintable-erc20-transfer)

### What are FxChild and FxRoot?

`FxChild` (FxChild.sol) and `FxRoot` (FxRoot.sol) are main contracts on which mapping-less bridge works. It calls and passes data to user-defined methods on another chain without mapping.
`FxChild` (`FxChild.sol`) and `FxRoot` (`FxRoot.sol`) are the main contracts on which the bridge works. It calls and passes data to user-defined methods on another chain without needing a mapping. You can deploy your own `FxChild` and `FxRoot`, but there is no need. If you pass the data to the deployed instances of `FxChild` or `FxRoot`, the clients will pick up the data and pass it to the other chain.

### Deployment Addresses

**Mumbai**

Expand All @@ -47,10 +70,45 @@ https://wiki.polygon.technology/docs/develop/l1-l2-communication/matic-to-ethere
| [FxRoot (Ethereum Mainnet)](https://etherscan.io/address/0xfe5e5d361b2ad62c541bab87c45a0b9b018389a2#code) | `0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2` |
| [FxChild (Matic Mainnnet)](https://explorer-mainnet.maticvigil.com/address/0x8397259c983751DAf40400790063935a11afa28a/contracts) | `0x8397259c983751DAf40400790063935a11afa28a` |

You can deploy your own `FxChild` and `FxRoot`, but no need. Except you want to have some fun and have extra ETH to throw away.
### Development

### What can I build with it?
This project can be compiled and tested with Hardhat and Foundry. Hardhat unit tests are located in [/hardhat](/hardhat) and Foundry unit + invariant tests can be found in the [/test](/test) directory.

- Arbitrary state bridge (examples/state-transfer)
- Normal ERC20 bridge (examples/erc2-transfer)
- ERC20 token generator bridge (example/mintable-erc20-transfer)
- Setup: `yarn install` and/or `forge install`
- Compile: `yarn build` and/or `forge build`
- Test: `yarn test` and/or `forge test -vvv`
- Coverage: `yarn coverage`
- Lint: `yarn lint`, `yarn prettier:write`

#### Proof Generation

A common question is how to generate proofs for the bridge. We'll explain what that means, and then list solutions.

To withdraw tokens on the root chain, first we call the relevant `withdraw()` method the child tunnel contract (which burn the respective tokens on child); and we use this transaction hash to generate proof of inclusion which acts as the argument to receiveMessage() in the respective root tunnel contract. Please see [here](https://wiki.polygon.technology/docs/pos/design/bridge/l1-l2-communication/fx-portal/#withdraw-tokens-on-the-root-chain).

To generate the proof, you can either use the [proof generation API](https://proof-generator.polygon.technology/api/v1/matic/exit-payload/%7BburnTxHash%7D?eventSignature=%7BeventSignature%7D) hosted by Polygon or you can also spin up your own proof generation API by following the instructions [here](https://github.com/maticnetwork/proof-generation-api).

The test suite also replicates proof generation (located at [hardhat/tunnel/payload](hardhat/tunnel/payload)), the following _hardhat task_ can help generating the proof for custom chains.

**Usage**: `npx hardhat exit-proof --help`

```
hardhat [GLOBAL OPTIONS] exit-proof [--sig <STRING>] --tx <STRING>
OPTIONS:
--sig log event hex signature (defaults to 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036 for `MessageSent(bytes)`)
--tx burn transaction hash
exit-proof: Generates exit proof for the given burn transaction hash
```

**Example**: `npx hardhat exit-proof --network polygon --tx 0x1cfc2658719e6d1753e091ce4515507711fe649269e75023c0f1123cd6e37c1a`

```
➜ npx hardhat exit-proof --network polygon --tx 0x1cfc2658719e6d1753e091ce4515507711fe649269e75023c0f1123cd6e37c1a
0xf909988201f4a0c8e08649aed43a802751213ece497804bd3acaee5d237326e0839c413b0920408402ae4af38464ae328da0d4ab5e911c81df7bfdc20e816de49c97f4808fcb1bcad63e328d0bca15a099e9a05e130cf2c4fb5778776309c95af5ca17ecbb47f6d3fc81c09bf110786269e2a6b903e702f903e3018355f7a2b9010000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000001000000008000000000000000000000000000000000000000000000000008000000800008000000000000000100000000000000000000020000000000000000000800000000000040000080000018000004000040000000040000000000000000000000020000000000000000000000000000200000000000001000000000000000000000000000000000000000000000004000000002000000000401000000000000000000000000000000120020000020000000100000000000000000000000000000001000000000000000000000100000f902d8f89b94aaf7701db5f8704450c6db28db99ea0a927e76adf863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000086eb278eeed79a44b5e3c83a012b96aa450912aba00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000087de5c5bd1dccf709cf8f994d531cf2142d9b9dc8b077df3c4e93b46e7cf879ae1a08c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036b8c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080000000000000000000000000922ac473a3cc241fd3a0049ed14536452d58d73c000000000000000000000000aaf7701db5f8704450c6db28db99ea0a927e76ad00000000000000000000000086eb278eeed79a44b5e3c83a012b96aa450912ab000000000000000000000000000000000000000000000087de5c5bd1dccf709cf9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a000000000000000000000000086eb278eeed79a44b5e3c83a012b96aa450912aba00000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0b8a00000000000000000000000000000000000000000000000000004f478e611780000000000000000000000000000000000000000000000000000e5dc5800087ecc000000000000000000000000000000000000000000000377f97e15a609a765bd00000000000000000000000000000000000000000000000000e0e7df19f706cc000000000000000000000000000000000000000000000377f9830a1eefb8ddbdb90537f90534f891a02dad7ffa3e44092c885002e5d2a48f58793d842ccc99aeccdb23c0094ac32c7da04696502faee79a586bd17877e2d1a66dd8dc0af8381fc488017c091e09dd3024a0360e2917de87f795b9350a7c29785a74da6582a4aeac0f20890cb0ac9820178c8080808080a0e2c9ed1fad4ea1a707e92bd2823e14a47f3cd5ff74258255c5b4961656bb4d098080808080808080f8b1a0299225ca484915f0ae642515e04aa9ddb2a86388f4404760715fa012f910ad28a0262c2288a6a1205fb045b10c14a9cfbac0196f9bb09b49e6523d90b4b8837cf5a01f727d97002d78492609ee434fc6daf0ab9f8347c393f488a178a59ad79775b7a0aa49afed4d9c80d7146bd606a9b111859a7b2b163e99b6320913a0977f1716aba026620528634fdd31f0bcbe97eef787f9244cf317928675c6da146d416ec282a4808080808080808080808080f903eb20b903e702f903e3018355f7a2b9010000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000001000000008000000000000000000000000000000000000000000000000008000000800008000000000000000100000000000000000000020000000000000000000800000000000040000080000018000004000040000000040000000000000000000000020000000000000000000000000000200000000000001000000000000000000000000000000000000000000000004000000002000000000401000000000000000000000000000000120020000020000000100000000000000000000000000000001000000000000000000000100000f902d8f89b94aaf7701db5f8704450c6db28db99ea0a927e76adf863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000086eb278eeed79a44b5e3c83a012b96aa450912aba00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000087de5c5bd1dccf709cf8f994d531cf2142d9b9dc8b077df3c4e93b46e7cf879ae1a08c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036b8c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080000000000000000000000000922ac473a3cc241fd3a0049ed14536452d58d73c000000000000000000000000aaf7701db5f8704450c6db28db99ea0a927e76ad00000000000000000000000086eb278eeed79a44b5e3c83a012b96aa450912ab000000000000000000000000000000000000000000000087de5c5bd1dccf709cf9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a000000000000000000000000086eb278eeed79a44b5e3c83a012b96aa450912aba00000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0b8a00000000000000000000000000000000000000000000000000004f478e611780000000000000000000000000000000000000000000000000000e5dc5800087ecc000000000000000000000000000000000000000000000377f97e15a609a765bd00000000000000000000000000000000000000000000000000e0e7df19f706cc000000000000000000000000000000000000000000000377f9830a1eefb8ddbd82002201
```
### Future Plans

Polygon has [announced](https://polygon.technology/blog/polygon-2-0-polygon-pos-zk-layer-2) its intent to migrate the chain to a zk validium. This would mean changes to the architecture and infrastructure. One solution that has been discussed is an [LXLY Bridge](https://www.youtube.com/watch?v=z44yN5ApOE8), a bridge structure developed for zkEVM. ([Alternative presentation](https://www.youtube.com/watch?v=sIbw5qqiXFk&t=2079s) timestamped at the section about the bridge)
5 changes: 4 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ src = 'contracts'
test = 'test'
libs = ['lib']
out = 'out'
cache_path = 'forge-cache'
cache_path = 'forge-cache'
verbosity = 2
solc_version = '0.8.17'
optimizer_runs = 200
via_ir = false
remappings = [
"@utils=test/utils/",
"@handlers=test/handlers/",
Expand Down
31 changes: 26 additions & 5 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,28 @@ import "hardhat-contract-sizer";
import "hardhat-gas-reporter";

import { HardhatUserConfig } from "hardhat/types";
import { task } from "hardhat/config";

let accounts: any = [];
const importToml = require("import-toml");
const foundryConfig = importToml.sync("foundry.toml");

if (process.env.PRIVATE_KEY) {
accounts = [`0x${process.env.PRIVATE_KEY}`, ...accounts];
}
const accounts = process.env.PRIVATE_KEY
? [`0x${process.env.PRIVATE_KEY}`]
: [];

task("exit-proof", "Generates exit proof for the given burn transaction hash")
.addParam("tx", "burn transaction hash")
.addOptionalParam(
"sig",
"log event hex signature (defaults to 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036 for `MessageSent(bytes)`)"
)
.setAction(async (args, hre) => {
const { buildPayloadForExit } = require("./hardhat/tunnel/payload/payload");
console.log(
(await buildPayloadForExit(args.tx, hre.ethers.provider, args.sig))
.burnProof
);
});

/**
* @type import('hardhat/config').HardhatUserConfig
Expand Down Expand Up @@ -44,10 +60,15 @@ export default {
},
},
solidity: {
version: "0.8.17",
version: foundryConfig.profile.default.solc_version,
settings: {
viaIR: foundryConfig.profile.default.via_ir,
optimizer: {
enabled: true,
runs: foundryConfig.profile.default.optimizer_runs,
},
metadata: {
bytecodeHash: "none",
},
},
},
Expand Down
11 changes: 6 additions & 5 deletions hardhat/tunnel/payload/payload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,13 @@ export function getBlockHeader(block: IBaseBlock) {

export async function buildPayloadForExit(
burnTxHash: string,
provider = ethers.provider,
logEventSig = "0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036",
isFast = false
) {
const requestConcurrency = 0;
const receipt = await ethers.provider.getTransactionReceipt(burnTxHash);
const block = await ethers.provider.send("eth_getBlockByNumber", [
const receipt = await provider.getTransactionReceipt(burnTxHash);
const block = await provider.send("eth_getBlockByNumber", [
ethers.utils.hexValue(receipt.blockNumber),
true,
]);
Expand All @@ -150,12 +151,12 @@ export async function buildPayloadForExit(
const headers = await getHeaders(
rootBlockInfo.start,
rootBlockInfo.end,
ethers.provider
provider
);
const tree = new MerkleTree(headers);

const fullBlockHeader = getBlockHeader(
(await ethers.provider.send("eth_getBlockByNumber", [
(await provider.send("eth_getBlockByNumber", [
ethers.utils.hexValue(block.number),
true,
])) as unknown as IBaseBlock
Expand All @@ -170,7 +171,7 @@ export async function buildPayloadForExit(
requestConcurrency,
await Promise.all(
block.transactions.map((tx: any) =>
ethers.provider.getTransactionReceipt(tx.hash)
provider.getTransactionReceipt(tx.hash)
)
)
);
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@
"hardhat-contract-sizer": "^2.0.3",
"hardhat-deploy": "0.11.30",
"hardhat-gas-reporter": "1.0.9",
"import-toml": "^1.0.0",
"prettier": "^2.8.7",
"prettier-plugin-solidity": "^1.1.3",
"solhint": "^3.4.0",
"solidity-coverage": "0.8.2",
"ts-node": "^10.3.0",
"typechain": "^5.1.2",
"typescript": "^4.4.4",
"prettier": "^2.8.7",
"solhint": "^3.4.0",
"prettier-plugin-solidity": "^1.1.3"
"typescript": "^4.4.4"
},
"dependencies": {
"@ethereumjs/block": "^3.6.1",
Expand Down
2 changes: 1 addition & 1 deletion slither.config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"detectors_to_exclude": "solc-version,naming-convention,similar-names,missing-zero-check,events-access,reentrancy-events,assembly,too-many-digits,boolean-equal,immutable-states,uninitialized-local,unused-return",
"filter_paths": "node_modules|test|lib"
"filter_paths": "(node_modules/|test/|lib/)"
}
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,11 @@
"@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0"

"@iarna/toml@^2.2.5":
version "2.2.5"
resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c"
integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==

"@jridgewell/resolve-uri@^3.0.3":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721"
Expand Down Expand Up @@ -5321,6 +5326,13 @@ import-fresh@^3.2.1:
parent-module "^1.0.0"
resolve-from "^4.0.0"

import-toml@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/import-toml/-/import-toml-1.0.0.tgz#e5057c3ae694cc98cc9bf4c099222c20480765fb"
integrity sha512-TkYSG1Rs9GiKk+hE/+yzugkmB6RY6llF2BgfxjLMZEg1QV36WUxrqnGWzb+ZdU61v5Hn3UWk7ePADdymFERpvA==
dependencies:
"@iarna/toml" "^2.2.5"

imul@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/imul/-/imul-1.0.1.tgz#9d5867161e8b3de96c2c38d5dc7cb102f35e2ac9"
Expand Down

0 comments on commit 296ac8d

Please sign in to comment.