Docs improvements and prep for deduping with docs repo (#48)

* Structure README for docs

* README updates

* Address pr comments

* Document address recipient
pull/2435/head
Yorke Rhodes 2 years ago committed by GitHub
parent aff4e3a908
commit f967760dc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 235
      README.md
  2. 2
      contracts/HypNative.sol
  3. 3
      contracts/libs/TokenRouter.sol

@ -1,17 +1,124 @@
# Hyperlane Warp Route
# Hyperlane Warp Routes
This repo contains the base Hyperlane ERC20 and ERC721 tokens (HypERC20 and HypERC721). These tokens extend the base standards with an additional `transferRemote` function. Warp Routes make any token or native asset interchain without custom contracts. Read more about Warp Routes and how to deploy your own at [Warp API docs](https://docs.hyperlane.xyz/docs/developers/warp-api).
This repo contains contracts, deployment, and SDK tooling for Hyperlane Warp Routes.
**NOTE:** ERC721 collateral variants are assumed to [enumerable](https://docs.openzeppelin.com/contracts/4.x/api/token/erc721#IERC721Enumerable) and [metadata](https://docs.openzeppelin.com/contracts/4.x/api/token/erc721#IERC721Metadata) compliant.
## Warp Route Architecture
## Versions
A *warp route* is a collection of [`TokenRouter`](./contracts/libs/TokenRouter.sol) contracts deployed across a set of Hyperlane chains. These contracts leverage the `Router` pattern to implement access control and routing logic for remote token transfers. These contracts send and receive [`Message`](./contracts/libs/Message.sol)s which encode payloads containing a transfer `amount` and `recipient` address.
| Git Ref | Release Date | Notes |
| ------- | ------------ | ----- |
| [audit-v2-remediation]() | 2023-02-15 | Hyperlane V2 Audit remediation |
| [main]() | ~ | Bleeding edge |
```mermaid
%%{ init: {
"theme": "neutral",
"themeVariables": {
"mainBkg": "#025AA1",
"textColor": "white",
"clusterBkg": "white"
},
"themeCSS": ".edgeLabel { color: black }"
}}%%
graph LR
subgraph "Ethereum"
HYP_E[TokenRouter]
style HYP_E fill:orange
Mailbox_E[(Mailbox)]
end
subgraph "Polygon"
HYP_P[TokenRouter]
style HYP_P fill:orange
Mailbox_P[(Mailbox)]
end
subgraph "Gnosis"
HYP_G[TokenRouter]
style HYP_G fill:orange
Mailbox_G[(Mailbox)]
end
HYP_E -. "router" .- HYP_P -. "router" .- HYP_G
```
The Token Router contract comes in several flavors and a warp route can be composed of a combination of these flavors.
- [`Native`](./contracts/HypNative.sol) - for warping native assets (e.g. ETH) from the canonical chain
- [`Collateral`](./contracts/HypERC20Collateral.sol) - for warping tokens, ERC20 or ERC721, from the canonical chain
- [`Synthetic`](./contracts/HypERC20.sol) - for representing tokens, Native/ERC20 or ERC721, on a non-canonical chain
## Interchain Security Models
Warp routes are unique amongst token bridging solutions because they provide modular security. Because the `TokenRouter` implements the `IMessageRecipient` interface, it can be configured with a custom interchain security module. Please refer to the relevant guide to specifying interchain security modules on the [Messaging API receive docs](https://docs.hyperlane.xyz/docs/apis/messaging-api/receive#interchain-security-modules).
## Remote Transfer Lifecycle Diagrams
To initiate a remote transfer, users call the `TokenRouter.transferRemote` function with the `destination` chain ID, `recipient` address, and transfer `amount`.
```solidity
interface TokenRouter {
function transferRemote(
uint32 destination,
bytes32 recipient,
uint256 amount
) public returns (bytes32 messageId);
}
```
**NOTE:** The [Relayer](https://docs.hyperlane.xyz/docs/protocol/agents/relayer) shown below must be compensated. Please refer to the relevant guide on [paying for interchain gas](https://docs.hyperlane.xyz/docs/build-with-hyperlane/guides/paying-for-interchain-gas) on the `messageID` returned from the `transferRemote` call.
Depending on the flavor of TokenRouter on the source and destination chain, this flow looks slightly different. The following diagrams illustrate these differences.
### Transfer Alice's `amount` native ETH from Ethereum to Bob on Polygon
```mermaid
%%{ init: {
"theme": "neutral",
"themeVariables": {
"mainBkg": "#025AA1",
"textColor": "white",
"clusterBkg": "white"
},
"themeCSS": ".edgeLabel { color: black }"
}}%%
graph TB
Bob((Bob))
style Bob fill:black
Alice((Alice))
style Alice fill:black
## Remote Transfer Lifecycle
Relayer([Relayer])
subgraph "Ethereum"
HYP_E[NativeTokenRouter]
style HYP_E fill:orange
Mailbox_E[(Mailbox)]
end
Alice == "transferRemote(Polygon, Bob, amount)\n{value: amount}" ==> HYP_E
linkStyle 0 color:green;
HYP_E -- "dispatch(Polygon, (Bob, amount))" --> Mailbox_E
subgraph "Polygon"
HYP_P[SyntheticTokenRouter]
style HYP_P fill:orange
Mailbox_P[(Mailbox)]
end
Mailbox_E -. "indexing" .-> Relayer
Relayer == "process(Ethereum, (Bob, amount))" ==> Mailbox_P
Mailbox_P -- "handle(Ethereum, (Bob, amount))" --> HYP_P
HYP_E -. "router" .- HYP_P
HYP_P -- "mint(Bob, amount)" --> Bob
linkStyle 6 color:green;
```
### Transfer Alice's ERC20 `amount` from Ethereum to Bob on Polygon
```mermaid
%%{ init: {
@ -19,7 +126,7 @@ This repo contains the base Hyperlane ERC20 and ERC721 tokens (HypERC20 and HypE
"themeVariables": {
"mainBkg": "#025AA1",
"textColor": "white",
"clusterBkg": "beige"
"clusterBkg": "white"
},
"themeCSS": ".edgeLabel { color: black }"
}}%%
@ -27,54 +134,99 @@ This repo contains the base Hyperlane ERC20 and ERC721 tokens (HypERC20 and HypE
graph TB
Alice((Alice))
Bob((Bob))
Validator((Validator))
Relayer((Relayer))
%% Watcher((Watcher))
style Alice fill:black
style Bob fill:black
Relayer([Relayer])
subgraph "Ethereum"
Token_E[ERC20]
HYP_E[HYP-ERC20]
M_E[(Mailbox)]
%% POS_E[Proof of Stake]
style Token_E fill:green
HYP_E[CollateralTokenRouter]
style HYP_E fill:orange
Mailbox_E[(Mailbox)]
end
Alice == "0. approve(HYP, infinity)" ==> Token_E
Alice == "1. transferRemote(Polygon, Bob, 5)" ==> HYP_E
Token_E -- "2. transferFrom(Alice, 5)" --> HYP_E
HYP_E -- "3. dispatch(Polygon, HYP, (Bob, 5))" --> M_E
Alice == "approve(CollateralTokenRouter, infinity)" ==> Token_E
Alice == "transferRemote(Polygon, Bob, amount)" ==> HYP_E
Token_E -- "transferFrom(Alice, amount)" --> HYP_E
linkStyle 2 color:green;
HYP_E -- "dispatch(Polygon, (Bob, amount))" --> Mailbox_E
subgraph "Polygon"
HYP_P[SyntheticRouter]
style HYP_P fill:orange
Mailbox_P[(Mailbox)]
end
M_E-."indexing".->Relayer
%% M_E-."indexing".->Watcher
M_E -. "indexing" .-> Validator
Mailbox_E -. "indexing" .-> Relayer
%% Validator == "staking" ==> POS_E
%% Watcher == "slashing" ==> POS_E
Validator -. "signing" .-> ISM_STORE
Relayer == "process(Ethereum, (Bob, amount))" ==> Mailbox_P
Mailbox_P -- "handle(Ethereum, (Bob, amount))" --> HYP_P
subgraph "Cloud Storage"
ISM_STORE[(ISM\nMetadata)]
end
HYP_E -. "router" .- HYP_P
HYP_P -- "mint(Bob, amount)" --> Bob
linkStyle 8 color:green;
```
### Transfer Alice's `amount` synthetic MATIC from Ethereum back to Bob as native MATIC on Polygon
```mermaid
%%{ init: {
"theme": "neutral",
"themeVariables": {
"mainBkg": "#025AA1",
"textColor": "white",
"clusterBkg": "white"
},
"themeCSS": ".edgeLabel { color: black }"
}}%%
ISM_STORE -. "metadata" .-> Relayer
ISM_STORE -. "moduleType" .- ISM_P
%% Watcher -. "indexing" .- ISM_P
graph TB
Bob((Bob))
style Bob fill:black
Alice((Alice))
style Alice fill:black
Relayer == "4. process(metadata, Ethereum, HYP, (Bob, 5))"==> M_P
Relayer([Relayer])
subgraph "Polygon"
ISM_P[ISM]
M_P[(Mailbox)]
HYP_P[HYP-ERC20]
subgraph "Ethereum"
HYP_E[SyntheticTokenRouter]
style HYP_E fill:orange
Mailbox_E[(Mailbox)]
end
M_P -- "6. handle(Ethereum, (Bob, 5))" --> HYP_P
M_P -- "5. verify(metadata, Ethereum, (Bob, 5))" --> ISM_P
Alice == "transferRemote(Polygon, Bob, amount)" ==> HYP_E
Alice -- "burn(Alice, amount)" --> HYP_E
linkStyle 1 color:green;
HYP_E -- "dispatch(Polygon, (Bob, amount))" --> Mailbox_E
subgraph "Polygon"
HYP_P[NativeTokenRouter]
style HYP_P fill:orange
Mailbox_P[(Mailbox)]
end
ISM_P -. "interchainSecurityModule" .- HYP_P
HYP_P -- "7. mint(Bob, 5)" --> Bob
Mailbox_E -. "indexing" .-> Relayer
Relayer == "process(Ethereum, (Bob, amount))" ==> Mailbox_P
Mailbox_P -- "handle(Ethereum, (Bob, amount))" --> HYP_P
HYP_E -. "router" .- HYP_P
HYP_P -- "transfer(){value: amount}" --> Bob
linkStyle 7 color:green;
```
**NOTE:** ERC721 collateral variants are assumed to [enumerable](https://docs.openzeppelin.com/contracts/4.x/api/token/erc721#IERC721Enumerable) and [metadata](https://docs.openzeppelin.com/contracts/4.x/api/token/erc721#IERC721Metadata) compliant.
## Versions
| Git Ref | Release Date | Notes |
| ------- | ------------ | ----- |
| [audit-v2-remediation]() | 2023-02-15 | Hyperlane V2 Audit remediation |
| [main]() | ~ | Bleeding edge |
## Setup for local development
```sh
@ -99,3 +251,4 @@ yarn lint
## Learn more
For more information, see the [Hyperlane documentation](https://docs.hyperlane.xyz/docs/introduction/readme).

@ -35,7 +35,7 @@ contract HypNative is TokenRouter {
uint32 _destination,
bytes32 _recipient,
uint256 _amount
) external payable override returns (bytes32 messageId) {
) public payable override returns (bytes32 messageId) {
require(msg.value >= _amount, "Native: amount exceeds msg.value");
uint256 gasPayment = msg.value - _amount;
messageId = _dispatchWithGas(

@ -11,6 +11,7 @@ import {Message} from "./Message.sol";
*/
abstract contract TokenRouter is GasRouter {
using TypeCasts for bytes32;
using TypeCasts for address;
using Message for bytes;
/**
@ -50,7 +51,7 @@ abstract contract TokenRouter is GasRouter {
uint32 _destination,
bytes32 _recipient,
uint256 _amountOrId
) external payable virtual returns (bytes32 messageId) {
) public payable virtual returns (bytes32 messageId) {
bytes memory metadata = _transferFromSender(_amountOrId);
messageId = _dispatchWithGas(
_destination,

Loading…
Cancel
Save