Skip to content

Commit 2127517

Browse files
authored
Merge pull request #67 from BootNodeDev/decouple-base
Decouple base
2 parents a01408f + 303c474 commit 2127517

15 files changed

+2811
-1229
lines changed

solidity/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ export ITT_INPUT = "TOKEN INPUT ADDRESS"
3232
export ITT_OUTPUT = "TOKEN OUTPUT ADDRESS"
3333
export AMOUNT_IN = "AMOUNT IN"
3434
export AMOUNT_OUT = "AMOUNT OUT"
35+
export SENDER_NONCE = "SENDER_NONCE"
3536
export DESTINATION_DOMAIN = "DESTINATION DOMAIN ID"

solidity/README.md

Lines changed: 72 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,63 @@
1-
# ERC7683 Router
1+
# ERC7683 Reference Implementation
22

3-
A reference ERC7683 implementation
3+
## Overview
44

5-
TODO - add some more description
5+
This project is centered around the [Base7683](./src/Base7683.sol) contract, which serves as the foundational component
6+
for implementing the interfaces defined in the
7+
[ERC7683 specification](https://github.com/across-protocol/ERCs/blob/master/ERCS/erc-7683.md). The contract is designed
8+
to be highly flexible, supporting any `orderDataType` and `orderData`. The logic for handling specific `orderData` types
9+
within the process of resolving and filling orders is intentionally left unimplemented, allowing inheriting contracts to
10+
define this behavior.
611

7-
## Deploy a Router7683
12+
While adhering to the `ERC7683` standard, `Base7683` introduces additional functionality for `settling` and `refunding`
13+
orders. These functions are not part of the `ERC7683` specification but are included to provide a unified interface for
14+
solvers and users across all implementations built on this framework.
15+
16+
Inheriting contracts must implement several key internal functions to define their specific logic for order resolution,
17+
filling, settlement, and refunds. These include:
18+
19+
- `_resolveOrder(GaslessCrossChainOrder memory _order)` and `_resolveOrder(OnchainCrossChainOrder memory _order)` for
20+
resolving orders into a hydrated format.
21+
- `_fillOrder(bytes32 _orderId, bytes calldata _originData, bytes calldata _fillerData)` for processing and filling
22+
orders.
23+
- `_settleOrders(bytes32[] calldata _orderIds, bytes[] memory _ordersOriginData, bytes[] memory _ordersFillerData)` for
24+
settling batches of orders.
25+
- `_refundOrders` for both `OnchainCrossChainOrder` and `GaslessCrossChainOrder` types, enabling the implementation of
26+
specific refund logic.
27+
- `_localDomain()` to retrieve the local domain identifier.
28+
- `_getOrderId` for computing unique identifiers for both `GaslessCrossChainOrder` and `OnchainCrossChainOrder` types.
29+
30+
These functions ensure that each inheriting contract provides its specific behavior while maintaining a consistent
31+
interface across the framework. You'll find more details of this function interfaces documented on the
32+
[Base7683](./src/Base7683.sol).
33+
34+
As reference, the following contracts build upon `Base7683`:
35+
36+
1. [BasicSwap7683](./src/BasicSwap7683.sol) The `BasicSwap7683` contract extends `Base7683` by implementing logic for a
37+
specific `orderData` type as defined in the [OrderEncoder](./src/libs/OrderEncoder.sol). This implementation
38+
facilitates token swaps, enabling the exchange of an `inputToken` on the origin chain for an `outputToken` on the
39+
destination chain.
40+
41+
2. [Hyperlane7683](./src/Hyperlane7683.sol) The `Hyperlane7683` contract builds on `BasicSwap7683` by integrating
42+
`Hyperlane` as the interchain messaging layer. This layer ensures seamless communication between chains during order
43+
execution.
44+
45+
## Extensibility
46+
47+
Both `BasicSwap7683` and `Hyperlane7683` are designed to be modular and extensible. Developers can use them as reference
48+
implementations to create custom solutions. For example:
49+
50+
- To implement a different `orderData` type, you could replace `BasicSwap7683` with a new contract that inherits from
51+
`Base7683`. The `Hyperlane7683` contract can remain unchanged and continue to provide messaging functionality.
52+
- Alternatively, you could replace the Hyperlane-based messaging layer in `Hyperlane7683` with another interchain
53+
messaging protocol while retaining the `BasicSwap7683` logic.
54+
55+
This modular approach enables a high degree of flexibility, allowing developers to adapt the framework to various use
56+
cases and requirements.
57+
58+
## Scripts
59+
60+
### Deploy
861

962
- Run `npm install` from the root of the monorepo to install all the dependencies
1063
- Create a `.env` file base on the [.env.example file](./.env.example) file, and set the required variables depending
@@ -19,7 +72,7 @@ Set the following environment variables required for running all the scripts, on
1972
If the network is not listed under the `rpc_endpoints` section of the [foundry.toml file](./foundry.toml) you'll have to
2073
add a new entry for it.
2174

22-
For deploying the router you have to run the `npm run run:deployRouter7683`. Make sure the following environment
75+
For deploying the router you have to run the `npm run run:deployHyperlane7683`. Make sure the following environment
2376
variable are set:
2477

2578
- `DEPLOYER_PK`: deployer private key
@@ -29,10 +82,12 @@ variable are set:
2982
- `PROXY_ADMIN_OWNER`: address of the ProxyAdmin owner, `ROUTER_OWNER` would be used if this is not set. The router is
3083
deployed using a `TransparentUpgradeableProxy`, so a ProxyAdmin contract is deployed and set as the admin of the
3184
proxy.
32-
- `HYPERLANE7683_SALT`: a single use by chain salt for deploying the the router. Make sure you use the same on all chains
33-
so the routers are deployed all under the same address.
85+
- `HYPERLANE7683_SALT`: a single use by chain salt for deploying the the router. Make sure you use the same on all
86+
chains so the routers are deployed all under the same address.
3487
- `DOMAINS`: the domains list of the routers to enroll, separated by commas
3588

89+
### Open an Order
90+
3691
For opening an onchain order you can run `npm run run:openOrder`. Make sure the following environment variable are set:
3792

3893
- `ROUTER_OWNER_PK`: the router's owner private key. Only the owner can enroll routers
@@ -44,6 +99,8 @@ For opening an onchain order you can run `npm run run:openOrder`. Make sure the
4499
- `AMOUNT_OUT`: amount out
45100
- `DESTINATION_DOMAIN`: destination domain id
46101

102+
---
103+
47104
## Usage
48105

49106
This is a list of the most frequently needed commands.
@@ -53,74 +110,60 @@ This is a list of the most frequently needed commands.
53110
Build the contracts:
54111

55112
```sh
56-
$ forge build
113+
$ yarn build
57114
```
58115

59116
### Clean
60117

61118
Delete the build artifacts and cache directories:
62119

63120
```sh
64-
$ forge clean
65-
```
66-
67-
### Compile
68-
69-
Compile the contracts:
70-
71-
```sh
72-
$ forge build
121+
$ yarn clean
73122
```
74123

75124
### Coverage
76125

77126
Get a test coverage report:
78127

79128
```sh
80-
$ forge coverage
129+
$ yarn coverage
81130
```
82131

83132
### Format
84133

85134
Format the contracts:
86135

87136
```sh
88-
$ forge fmt
137+
$ yarn sol:fmt
89138
```
90139

91140
### Gas Usage
92141

93-
Get a gas report:
94-
95-
```sh
96-
$ forge test --gas-report
97-
```
98-
99142
### Lint
100143

101144
Lint the contracts:
102145

103146
```sh
104-
$ npm run lint
147+
$ yarn lint
105148
```
106149

107150
### Test
108151

109152
Run the tests:
110153

111154
```sh
112-
$ forge test
155+
$ yarn test
113156
```
114157

115158
Generate test coverage and output result to the terminal:
116159

117160
```sh
118-
$ npm run test:coverage
161+
$ yarn test:coverage
119162
```
120163

121164
Generate test coverage with lcov report (you'll have to open the `./coverage/index.html` file in your browser, to do so
122165
simply copy paste the path):
123166

124167
```sh
125-
$ npm run test:coverage:report
168+
$ yarn test:coverage:report
126169
```

solidity/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
"prettier:check": "prettier --check \"**/*.{json,md,yml}\" --ignore-path \".prettierignore\"",
2828
"prettier:write": "prettier --write \"**/*.{json,md,yml}\" --ignore-path \".prettierignore\"",
2929
"test": "forge test -vvv",
30-
"test:coverage": "forge coverage",
31-
"test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage",
30+
"test:coverage": "forge coverage --no-match-coverage \"(test|mock|node_modules|script)\"",
31+
"test:coverage:report": "forge coverage --no-match-coverage \"(test|mock|node_modules|script)\" --report lcov && genhtml lcov.info --ignore-errors inconsistent,inconsistent --branch-coverage --output-dir coverage",
3232
"deployHyperlane7683": "forge script script/DeployHyperlane7683.s.sol:DeployHyperlane7683 -f $NETWORK --broadcast --verify --slow -vvv",
3333
"run:deployHyperlane7683": "dotenv-run-script deployHyperlane7683",
3434
"deployToken": "forge script script/DeployToken.s.sol:DeployToken -f $NETWORK --broadcast --verify --slow -vvv",

solidity/script/OpenOrder.s.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ contract OpenOrder is Script {
2828
address outputToken = vm.envAddress("ITT_OUTPUT");
2929
uint256 amountIn = vm.envUint("AMOUNT_IN");
3030
uint256 amountOut = vm.envUint("AMOUNT_OUT");
31-
uint256 senderNonce = Hyperlane7683(localRouter).senderNonce(sender);
31+
uint256 senderNonce = vm.envUint("SENDER_NONCE");
3232
uint32 originDomain = Hyperlane7683(localRouter).localDomain();
3333
uint256 destinationDomain = vm.envUint("DESTINATION_DOMAIN");
3434
uint32 fillDeadline = type(uint32).max;
@@ -45,6 +45,7 @@ contract OpenOrder is Script {
4545
senderNonce,
4646
originDomain,
4747
uint32(destinationDomain),
48+
TypeCasts.addressToBytes32(localRouter),
4849
fillDeadline,
4950
new bytes(0)
5051
);

0 commit comments

Comments
 (0)