Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f49f53b
forge install: devtools
gfournierPro May 9, 2025
06c09ee
forge install: layerzero-v2
gfournierPro May 9, 2025
8bb6a85
forge install: rlc-faucet-contract
gfournierPro May 9, 2025
91c7a70
forge install: openzeppelin-contracts
gfournierPro May 9, 2025
fcb4ee0
feat: Implement RLCAdapter and RLCOFT contracts with deployment scripts
gfournierPro May 13, 2025
0fd43c7
refactor: Clean up whitespace and formatting in contract scripts
gfournierPro May 13, 2025
5ff3398
feat: Implement cross-chain transfer scripts for RLC tokens between A…
gfournierPro May 14, 2025
c400115
feat: Update deployment scripts to use environment variables for addr…
gfournierPro May 14, 2025
dfd6e42
Refactor Ethereum to Arbitrum transfer scripts and update transaction…
gfournierPro May 14, 2025
1d2795a
feat: Add .env.template for Ethereum and Arbitrum Sepolia configurations
gfournierPro May 15, 2025
6eefe3a
refactor: Remove Foundry section and enhance README with detailed bri…
gfournierPro May 15, 2025
7a713a6
feat: Add detailed transaction data for cross-chain transfers from Ar…
gfournierPro May 15, 2025
dcc2ef6
feat: Add transaction details and receipts for Ethereum to Arbitrum t…
gfournierPro May 15, 2025
52e5b76
refactor: Clean up Makefile by removing unused targets and help section
gfournierPro May 15, 2025
3b71cff
refactor: Simplify README by removing detailed .env configuration sec…
gfournierPro May 15, 2025
22d9aea
feat: Implement EnvUtils library for updating environment variables i…
gfournierPro May 15, 2025
6ef8db5
Refactor code structure for improved readability and maintainability
gfournierPro May 15, 2025
e4d5e19
fix: Update RPC URLs for Ethereum and Arbitrum Sepolia configurations
gfournierPro May 15, 2025
db42713
feat(rlcoft.sol): Override decimals function to return 9 for the token
gfournierPro May 15, 2025
09b05f3
fix: Correct API key variable name for Blockscan to ETHERSCAN_API_KEY
gfournierPro May 15, 2025
f1b607f
feat(Makefile): Add verification targets for RLCAdapter and RLCOFT on…
gfournierPro May 15, 2025
5f6a184
fix(.gitignore): Update ignore rules for Foundry broadcast files
gfournierPro May 15, 2025
70d212d
add run latest
gfournierPro May 15, 2025
822f69e
clean up unnecessary transaction data.
gfournierPro May 15, 2025
f5c1400
feat: Add initial changelog for RLC OFT bridge system implementation
gfournierPro May 15, 2025
bf41432
refactor: Update environment variable names for LayerZero configuration
gfournierPro May 16, 2025
87e205c
refactor: Rename environment variables for RLC adapter and OFT addresses
gfournierPro May 16, 2025
f1a0a3d
fix: Update Arbitrum Sepolia RPC URL to the correct endpoint
gfournierPro May 16, 2025
1d74f14
refactor: Rename token configuration variables for RLC OFT
gfournierPro May 16, 2025
0a71ee3
fix: add EOF blank line
gfournierPro May 16, 2025
a4351e8
refactor(MakeFile): Move test and clean targets to the top
gfournierPro May 16, 2025
c15e285
fix(README): Update repository clone URL in
gfournierPro May 16, 2025
6212a9c
docs(README): Add instructions for creating and editing .env file
gfournierPro May 16, 2025
78e7521
refactor(Makefile): Rename configuration and token transfer targets f…
gfournierPro May 16, 2025
e932c70
fix: Correct constructor order in RLCAdapter and RLCOFT contracts
gfournierPro May 16, 2025
e1cf4ca
fix: Update SPDX license identifiers from UNLICENSED to Apache-2.0 in…
gfournierPro May 16, 2025
20b2a14
docs(RLCOFT): Improve comment clarity for approveAndCall function
gfournierPro May 16, 2025
9c6eccc
feat: Introduce ITokenSpender interface and update RLCOFT to use it
gfournierPro May 16, 2025
84f348b
refactor: Simplify contract names in deployment and configuration scr…
gfournierPro May 16, 2025
67af7c0
fix: Rename DELEGATE_ADDRESS and RECEIVER_ADDRESS to SENDER_ADDRESS i…
gfournierPro May 16, 2025
d50588c
refactor: Change variable declarations for RLCAdapter and RLCOFT to l…
gfournierPro May 16, 2025
e046bcb
fix(Makefile): Remove unnecessary source command in send-tokens-to-se…
gfournierPro May 16, 2025
f9c877f
docs: Update README for clarity and add contract overview section
gfournierPro May 16, 2025
47297f4
docs: Update usage section in README for clarity on bridging RLC tokens
gfournierPro May 16, 2025
72cf079
chore: Comment out test step in CI workflow for future implementation
gfournierPro May 16, 2025
b3c2972
fix(Makefile): Remove unused .PHONY target for send-tokens-to-arbitru…
gfournierPro May 16, 2025
07144df
style: Clean up whitespace in multiple Solidity scripts for consistency
gfournierPro May 16, 2025
feadf9b
fix: Rename environment variable for Arbitrum Sepolia RLC OFT address…
gfournierPro May 16, 2025
a1238c1
fix: Rename scripts and Makefile targets for clarity and consistency
gfournierPro May 16, 2025
cabe6da
style: Add TODO comment to extract and document gas estimation function
gfournierPro May 16, 2025
fac839e
fix: Change behavior on missing .env file to revert instead of returning
gfournierPro May 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Ethereum Sepolia Configuration
SEPOLIA_RPC_URL="https://gateway.tenderly.co/public/sepolia"
LAYER_ZERO_SEPOLIA_ENDPOINT_ADDRESS=0x6EDCE65403992e310A62460808c4b910D972f10f
LAYER_ZERO_SEPOLIA_CHAIN_ID=40161 # LayerZero chain ID for Ethereum Sepolia
RLC_SEPOLIA_ADAPTER_ADDRESS=0x<deployed-rlc-adapter-address-on-sepolia>
RLC_SEPOLIA_ADDRESS=0x<rlc-token-address-on-sepolia>

# Arbitrum Sepolia Configuration
ARBITRUM_SEPOLIA_RPC_URL="https://arbitrum-sepolia.gateway.tenderly.co"
LAYER_ZERO_ARBITRUM_SEPOLIA_ENDPOINT_ADDRESS=0x6EDCE65403992e310A62460808c4b910D972f10f
LAYER_ZERO_ARBITRUM_SEPOLIA_CHAIN_ID=40231 # LayerZero chain ID for Arbitrum Sepolia
RLC_ARBITRUM_SEPOLIA_OFT_ADDRESS=0x<deployed-rlcoft-address-on-arbitrum-sepolia>

# Token Configuration for OFT
RLC_OFT_TOKEN_NAME="RLC OFT"
RLC_TOKEN_SYMBOL="RLC"

# Transaction Settings
SENDER_ADDRESS=0x<delegate-wallet-address>

# API Keys
ETHERSCAN_API_KEY=<your-etherscan-api-key>
ARBISCAN_API_KEY=<your-etherscan-api-key>

# Account info for script execution - can be private key or mnemonic, depending on configuration
ACCOUNT=<account-identifier-for-forge>
10 changes: 5 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ jobs:
run: |
forge build --sizes
id: build

- name: Run Forge tests
run: |
forge test -vvv
id: test
#TDO: Uncomment when tests are available
# - name: Run Forge tests
# run: |
# forge test -vvv
# id: test
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ out/
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/
# Foundry broadcast files
broadcast/*/*/run-*.json
!broadcast/*/*/run-latest.json


# Docs
docs/

# Dotenv file
.env
.last_deploy.json
12 changes: 12 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/devtools"]
path = lib/devtools
url = https://github.com/LayerZero-Labs/devtools
[submodule "lib/layerzero-v2"]
path = lib/layerzero-v2
url = https://github.com/LayerZero-Labs/layerzero-v2
[submodule "lib/rlc-faucet-contract"]
path = lib/rlc-faucet-contract
url = https://github.com/iExecBlockchainComputing/rlc-faucet-contract
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog

## vNEXT

### Added
- Initial implementation of RLC OFT (Optimistic Fungible Token) bridge system
- RLCOFT contract deployed on Arbitrum Sepolia with 9 decimal places
- RLCAdapter contract deployed on Ethereum Sepolia to bridge existing RLC token
- Cross-chain message passing functionality using LayerZero protocol
- Configuration scripts for trustless omnichain communication setup
- Token transfer capabilities between Ethereum Sepolia and Arbitrum Sepolia
- `approveAndCall` function for one-step approval and contract interaction
- Burn capability for RLCOFT tokens
- Comprehensive deployment scripts using Foundry
- Configuration utilities to set trusted remote addresses
- Verification targets for block explorer verification
- End-to-end cross-chain transfer test scripts
84 changes: 84 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Makefile for RLC OFT Project
-include .env

# Test and utility targets
test:
@echo "Running tests..."
forge test -vvv

clean:
@echo "Cleaning artifacts..."
forge clean

# Deployment targets
deploy-adapter:
@echo "Deploying RLCAdapter on SEPOLIA..."
forge script script/RLCAdapter.s.sol:Deploy \
--rpc-url $(SEPOLIA_RPC_URL) \
--account $(ACCOUNT) \
--broadcast \
-vvv

deploy-oft:
@echo "Deploying RLCOFT on Arbitrum SEPOLIA..."
forge script script/RLCOFT.s.sol:Deploy \
--rpc-url $(ARBITRUM_SEPOLIA_RPC_URL) \
--account $(ACCOUNT) \
--broadcast \
-vvv \

configure-adapter:
@echo "Configuring RLCAdapter on SEPOLIA..."
forge script script/ConfigureRLCAdapter.s.sol:Configure \
--rpc-url $(SEPOLIA_RPC_URL) \
--account $(ACCOUNT) \
--broadcast \
-vvv
configure-oft:
@echo "Configuring RLCOFT on Arbitrum SEPOLIA..."
forge script script/ConfigureRLCOFT.s.sol:Configure \
--rpc-url $(ARBITRUM_SEPOLIA_RPC_URL) \
--account $(ACCOUNT) \
--broadcast \
-vvv

send-tokens-to-arbitrum-sepolia:
@echo "Sending tokens cross-chain... from SEPOLIA to Arbitrum SEPOLIA"
forge script script/SendEthereumToArbitrum.s.sol:SendTokensToArbitrumSepolia \
--rpc-url $(SEPOLIA_RPC_URL) \
--account $(ACCOUNT) \
--broadcast \
-vvv

send-tokens-to-sepolia:
@echo "Sending tokens cross-chain... from Arbitrum SEPOLIA to SEPOLIA"
forge script script/SendArbitrumToEthereum.s.sol:SendTokensToSepolia \
--rpc-url $(ARBITRUM_SEPOLIA_RPC_URL) \
--account $(ACCOUNT) \
--broadcast \
-vvv

# Verification targets
verify-adapter:
@echo "Verifying RLCAdapter on Sepolia Etherscan..."
forge verify-contract \
--chain-id 11155111 \
--watch \
--constructor-args $(shell cast abi-encode "constructor(address,address,address)" $(RLC_SEPOLIA_ADDRESS) $(LAYER_ZERO_SEPOLIA_ENDPOINT_ADDRESS) $(SENDER_ADDRESS)) \
--etherscan-api-key $(ETHERSCAN_API_KEY) \
$(RLC_SEPOLIA_ADAPTER_ADDRESS) \
src/RLCAdapter.sol:RLCAdapter

verify-oft:
@echo "Verifying RLCOFT on Arbitrum Sepolia Etherscan..."
forge verify-contract \
--chain-id 421614 \
--watch \
--constructor-args $(shell cast abi-encode "constructor(string,string,address,address)" $(RLC_OFT_TOKEN_NAME) $(RLC_TOKEN_SYMBOL) $(LAYER_ZERO_ARBITRUM_SEPOLIA_ENDPOINT_ADDRESS) $(SENDER_ADDRESS)) \
--etherscan-api-key $(ARBISCAN_API_KEY) \
$(RLC_ARBITRUM_SEPOLIA_OFT_ADDRESS) \
src/RLCOFT.sol:RLCOFT

# Combined verification target
verify-all: verify-adapter verify-oft

150 changes: 109 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,134 @@
## Foundry
# RLC Layer Zero Bridge

**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**
This project implements a cross-chain token bridge for the RLC token between Ethereum and Arbitrum using LayerZero's OFT (Omnichain Fungible Token) protocol. It enables seamless token transfers between Ethereum Sepolia and Arbitrum Sepolia testnets.

Foundry consists of:
## Architecture

- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network.
- **Chisel**: Fast, utilitarian, and verbose solidity REPL.
The system consists of two main components:

## Documentation
1. **RLCAdapter (on Ethereum Sepolia)**: Wraps the existing RLC ERC-20 token to make it compatible with LayerZero's cross-chain messaging.
2. **RLCOFT (on Arbitrum Sepolia)**: A new token that's minted when RLC tokens are locked in the adapter on Ethereum, and burned when tokens are sent back.

https://book.getfoundry.sh/
[![Architecture Diagram](https://mermaid.ink/img/pako:eNqNVNtO4zAQ_RXLvAY2F3JpQEhpLrsPRUhQXqBoZRKXRjh2ZCdouf372nHSEhrYddV2MjnHZ-ZM4leYswLDED5wVG_AMllRIJdo73ViBdNmgzluK3CFa0ZKtIIaotblIr6VX7Bkj5ju0qflWXoZ2-bpj_LsbpeOClQ3mCtGH44oF9myT3_iLW5-p8tftwv0jPkN5gyktKhZSZseg2mhg73aI35fNny6dimnKpF_E-XL7H4R0eX8v4u4Fph3VasAMAoGG-_A4eHZmwWiuubsCQvQKHHxBkaWDPQObIMYESKAkBqfcP1FB3PAguWPuw1lc_ugY2kFLQSosBDoAb_15mqgjjucC2LOhDjMN6ikI7R0YYuWcYf2QIJJ-YT5h42lhRqnHFYgH5xLu3b1dT0qTweLhmnd7Rk56EQjJ_YU5mDecrpT2APEE91P9ZN82f2UV-lE919OKQPXlPx7Tj_BkiMq1mrTkWHbAvRvTpAQCV4DPLym65KQ8CD24izzDdFwSQ4PnMQ1576RM8J4eE9Q_njyiY-GV0Xz51bqZNmWb0eBnQXf8Vs1RM3NssSOzC03y4LANL_jkpeembjqs6u6WxPMD3xlnzE4N5jwUaAb_tDd6Mbgp7F9xlQTI4iestE_GuTlBBqwwrxCZSHPzFcFXUEpWuEVDGVY4DVqSaPOmXcJRW3Drp5pDkMpjg3Y1gVqcFIieUBVMFwjImS2RvSGsWoAyUsYvsI_MAysI8_yfNuZeY7tuUFgwGcYWjP3yLdN1_Jl5PiBab8b8KXbwDyaufbMOnYs27OsIPA8A3LWPmy2WrgoG8bP9ZnfHf2GPPpVN1qcy_cD85i1tJFKlj3UnHY8jXr_C5RA8AI)](https://mermaid.live/edit#pako:eNqNVNtO4zAQ_RXLvAY2F3JpQEhpLrsPRUhQXqBoZRKXRjh2ZCdouf372nHSEhrYddV2MjnHZ-ZM4leYswLDED5wVG_AMllRIJdo73ViBdNmgzluK3CFa0ZKtIIaotblIr6VX7Bkj5ju0qflWXoZ2-bpj_LsbpeOClQ3mCtGH44oF9myT3_iLW5-p8tftwv0jPkN5gyktKhZSZseg2mhg73aI35fNny6dimnKpF_E-XL7H4R0eX8v4u4Fph3VasAMAoGG-_A4eHZmwWiuubsCQvQKHHxBkaWDPQObIMYESKAkBqfcP1FB3PAguWPuw1lc_ugY2kFLQSosBDoAb_15mqgjjucC2LOhDjMN6ikI7R0YYuWcYf2QIJJ-YT5h42lhRqnHFYgH5xLu3b1dT0qTweLhmnd7Rk56EQjJ_YU5mDecrpT2APEE91P9ZN82f2UV-lE919OKQPXlPx7Tj_BkiMq1mrTkWHbAvRvTpAQCV4DPLym65KQ8CD24iyyDdFwSQ4PnMQ1576RM8J4eE9Q_njyiY-GV0Xz51bqZNmWb0eBnQXf8Vs1RM3NssSOzC03y4LANL_jkpeembjqs6u6WxPMD3xlnzE4N5jwUaAb_tDd6Mbgp7F9xlQTI4iestE_GuTlBBqwwrxCZSHPzFcFXUEpWuEVDGVY4DVqSaPOmXcJRW3Drp5pDkMpjg3Y1gVqcFIieUBVMFwjImS2RvSGsWoAyUsYvsI_MAysI8_yfNuZeY7tuUFgwGcYWjP3yLdN1_Jl5PiBab8b8KXbwDyaufbMOnYs27OsIPA8A3LWPmy2WrgoG8bP9ZnfHf2GPPpVN1qcy_cD85i1tJFKlj3UnHY8jXr_C5RA8AI)

## Prerequisites

- [Foundry](https://book.getfoundry.sh/getting-started/installation.html) for contract compilation and deployment
- Ethereum wallet with Sepolia ETH and Arbitrum Sepolia ETH for gas
- RLC tokens on Sepolia testnet for bridge testing

## Installation

1. Clone the repository
```bash
git clone https://github.com/iExecBlockchainComputing/rlc-multichain.git
cd rlc-multichain
```

2. Install dependencies
```bash
forge install
```

3. Create a `.env` file
```sh
cp .env.template .env # and edit .env content
```

## Contract Overview

Instead of duplicating code that may become outdated, here are links to the key contracts in the repository:

- [RLCAdapter.sol](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/main/src/RLCAdapter.sol) - Ethereum-side adapter that wraps the existing RLC token
- [RLCOFT.sol](https://github.com/iExecBlockchainComputing/rlc-multichain/blob/main/src/RLCOFT.sol) - Arbitrum-side token that implements the OFT standard

## Deployment

The deployment process involves four steps:

1. Deploy the RLCAdapter on Ethereum Sepolia:
```bash
make deploy-adapter
```

2. Deploy the RLCOFT on Arbitrum Sepolia:
```bash
make deploy-oft
```

3. Configure the RLCAdapter to trust the RLCOFT contract:
```bash
make configure-adapter
```

4. Configure the RLCOFT to trust the RLCAdapter contract:
```bash
make configure-oft
```

After deployment, update your `.env` file with the deployed contract addresses.

## Usage

### Build
### Bridge RLC

```shell
$ forge build
A. To send RLC tokens from Ethereum Sepolia to Arbitrum Sepolia:

```bash
make send-tokens-to-arbitrum-sepolia
```

### Test
This will:
1. Approve the RLCAdapter to spend your RLC tokens
2. Initiate the cross-chain transfer through LayerZero
3. Lock tokens in the adapter and mint equivalent tokens on Arbitrum

B. To send RLC tokens from Arbitrum Sepolia back to Ethereum Sepolia:

```shell
$ forge test
```bash
make send-tokens-to-sepolia
```

### Format
This will:
1. Burn RLCOFT tokens on Arbitrum
2. Send a cross-chain message to the adapter
3. Release the original RLC tokens on Ethereum

```shell
$ forge fmt
```
## How It Works

### Gas Snapshots
1. **Ethereum → Arbitrum:**
- User approves RLCAdapter to spend RLC tokens
- RLCAdapter locks the RLC tokens
- LayerZero delivers a message to RLCOFT
- RLCOFT mints equivalent tokens to the recipient on Arbitrum

```shell
$ forge snapshot
```
2. **Arbitrum → Ethereum:**
- User initiates transfer from RLCOFT
- RLCOFT burns the tokens
- LayerZero delivers a message to RLCAdapter
- RLCAdapter unlocks the original RLC tokens to the recipient on Ethereum

### Anvil
## Security Considerations

```shell
$ anvil
```
- The bridge security relies on LayerZero's security model
- Administrative functions are protected by the Ownable pattern
- Use caution when setting trusted remotes to prevent unauthorized cross-chain interactions
- Always test thoroughly on testnets before deploying to mainnet

### Deploy
## Gas Costs and Fees

```shell
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
```
LayerZero transactions require fees to cover:
1. Gas on the source chain
2. Gas on the destination chain (prepaid)
3. LayerZero relayer fees

### Cast
The scripts automatically calculate these fees and include them in the transaction.

```shell
$ cast <subcommand>
```
## Troubleshooting

### Help

```shell
$ forge --help
$ anvil --help
$ cast --help
```
## References

- [LayerZero Documentation](https://layerzero.gitbook.io/docs/)
- [OFT Contracts](https://github.com/LayerZero-Labs/solidity-examples/tree/main/contracts/token/oft)
- [iExec Platform Documentation](https://docs.iex.ec/)
Loading