This repo contains a set of smart contracts meant for enabling XERC20 token bridging through the Arbitrum canonical bridge, using two different approaches:
An example use case for this approach would be ezETH. ezETH is an ERC20 on L1 with an XERC20 representation on both L1 and L2. In order for Renzo to enable bridging the ezETH token it would need to:
- Deploy both
L1LockboxGateway
andL1LockboxGateway
- Set the previously deployed
L1LockboxGateway
as abridge
on the XERC20 ezETH - Make a proposal to Arbitrum DAO for registering the
ezETH on Arbitrum's router to be used with
the
L1LockboxGateway
, which should include:- Registering the ezETH on the router
- Remove from UI block-list
- Add L2 ezETH to L2ApprovalUtils
There are a few prerequisites to keep in mind for registering a token in the router associating it to a specific gateway.
First of all, the L1 counterpart of the token must conform to the ICustomToken interface. This means that:
- It must have a isArbitrumEnabled method that returns 0xb1
- It must have a method that makes an external call to L1CustomGateway.registerCustomL2Token specifying the address of the L2 contract, and to L1GatewayRouter.setGateway specifying the address of the custom gateway. These calls should be made only once to configure the gateway.
These methods are needed to register the token via the gateway contract. If the L1 contract does not include these methods and it is not upgradeable, registration could alternatively be performed in one of these ways:
- As a chain-owner registration via an Arbitrum DAO proposal.
- By wrapping your L1 token and registering the wrapped version of your token.
This approach uses an Adapter contract which is used for being able to permissionlessly register a non Arbitrum compatible token on the Arbitrum Router to be used with a Custom Gateway
In order to be able to use this approach it would be required to:
UI
- BootNode's UI PR to be merged (TODO add PR link)
Some trusted entity
- Deploy both
L1XERC20Gateway
andL1XERC20Gateway
XERC20 Token Issuer
- Deploy an
L1XERC20Adapter
if the XERC20 token - Call the
registerTokenOnL2
function on the deployedL1XERC20Adapter
- Set the
L1XERC20Gateway
as abridge
on the XERC20 token. WARNING: Token issuer must ensure the previous step was properly executed before this one. - Make a PR to Arbitrum's UI repository adding the L2 XERC20 token to L2ApprovalUtils
Deployment script documentation can be found here.
Foundry typically uses git submodules to manage dependencies, but this template uses Node.js packages because submodules don't scale.
This is how to install dependencies:
- Install the dependency using your preferred package manager, e.g.
bun install dependency-name
- Use this syntax to install from GitHub:
bun install github:username/repo-name
- Use this syntax to install from GitHub:
- Add a remapping for the dependency in remappings.txt, e.g.
dependency-name=node_modules/dependency-name
Note that OpenZeppelin Contracts is pre-installed, so you can follow that as an example.
This is a list of the most frequently needed commands.
Build the contracts:
$ forge build
Delete the build artifacts and cache directories:
$ forge clean
Compile the contracts:
$ forge build
Get a test coverage report:
$ forge coverage
Format the contracts:
$ forge fmt
Get a gas report:
$ forge test --gas-report
Lint the contracts:
$ bun run lint
Run the tests:
$ forge test
Generate test coverage and output result to the terminal:
$ bun run test:coverage
Generate test coverage with lcov report (you'll have to open the ./coverage/index.html
file in your browser, to do so
simply copy paste the path):
$ bun run test:coverage:report
This project is licensed under MIT.