Giter Club home page Giter Club logo

foundry-arbitrum's Introduction

foundry-arbitrum

๐Ÿšง Currently experimental and actively being dogfooded

๐Ÿšจ These utility mocks do not replace extensive testing (use of local nodes or testnet)

Reusable, mocked Arbitrum contracts to enable cross-chain message testing within the foundry environment

Assuming the messages are successful, is the state changing as expected?


Usage

forge install saucepoint/foundry-arbitrum

In the test files, inherit from ArbitrumTest

import {ArbitrumTest} from "foundry-arbitrum/ArbitrumTest.sol";

import {L1Contract} from "../src/L1Contract.sol";
import {L2Contract} from "../src/L2Contract.sol";

contract ExampleTest is Test, ArbitrumTest {
    L1Contract l1Contract;
    L2Contract l2Contract;

    function setUp() public {
        // Our L2 contract that will communicate with the L1 contract
        // via ArbSys precompile at address(0x64) (mocked and etched in ArbitrumTest)
        l2Contract = new L2Contract();

        // Our L1 contract that will communicate with the L2 contract
        // via inbox (mock deployed in ArbitrumTest)
        l1Contract = new L1Contract(address(inbox), address(l2Contract));

        l2Contract.setL1Target(address(l1Contract));
    }

    function testMessage() public {
        // assert how *succesful* cross-chain messages would modify state
        // (using the mocks implies that cross-chain messages are atomic & successful)
    }
}

Intended for contracts relying on the Arbitrum Inbox.sol and the ArbSys.sol precompile:

L1 Contract:

import {IInbox} from "@arbitrum/nitro-contracts/src/bridge/IInbox.sol";

// Arbitrum Inbox (message handler)
IInbox public inbox;

constructor(address _inbox, address _l2Target) {
    inbox = IInbox(_inbox);
    l2Target = _l2Target;
}

...

// calls `handleMessageFromL1(uint256 num)` on L2
bytes memory data = abi.encodeWithSelector(L2Contract.handleMessageFromL1.selector, number);

inbox.createRetryableTicket{value: msg.value}(
    l2Target, 0, maxSubmissionCost, msg.sender, msg.sender, maxGas, gasPriceBid, data
);

L2 Contract:

import {IArbSys} from "./interfaces/IArbSys.sol";

// canonical precompile used to send messages to L1
IArbSys constant arbsys = IArbSys(address(0x0000000000000000000000000000000000000064));

...

// calls `handleMessageFromL2(uint256 num)` on L1
bytes memory data = abi.encodeWithSelector(L1Contract.handleMessageFromL2.selector, number);
arbsys.sendTxToL1(l1Target, data);

foundry-arbitrum's People

Contributors

saucepoint avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.