Coder Social home page Coder Social logo

mw2000 / foundry-huff Goto Github PK

View Code? Open in Web Editor NEW

This project forked from huff-language/foundry-huff

0.0 0.0 0.0 314 KB

A Foundry Library for compiling, debugging, and working with Huff contracts in Solidity.

License: Apache License 2.0

Shell 2.44% Solidity 97.56%

foundry-huff's Introduction

Foundry x Huff

ci License Discord

A foundry library for working with huff contracts. Take a look at our project template to see an example project that uses this library.

Installing

First, install the huff compiler by running:

curl -L get.huff.sh | bash

Then, install this library with forge:

forge install huff-language/foundry-huff

Usage

The HuffDeployer is a Solidity library that takes a filename and deploys the corresponding Huff contract, returning the address that the bytecode was deployed to. To use it, simply import it into your file by doing:

import {HuffDeployer} from "foundry-huff/HuffDeployer.sol";

To compile contracts, you can use HuffDeployer.deploy(string fileName), which takes in a single string representing the filename's path relative to the src directory. Note that the file ending, i.e. .huff, must be omitted. Here is an example deployment (where the contract is located in src/test/contracts/Number.huff):

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.7.0 <0.9.0;

import {HuffDeployer} from "foundry-huff/HuffDeployer";

interface Number {
  function setNumber(uint256) external;
  function getNumber() external returns (uint256);
}

contract HuffDeployerExample {
  function deploy() public {
    // Deploy a new instance of src/test/contracts/Number.huff
    address addr = HuffDeployer.deploy("test/contracts/Number");

    // To call a function on the deployed contract, create an interface and wrap the address like so
    Number number = Number(addr);
  }
}

To deploy a Huff contract with constructor arguments, you can chain commands onto the HuffDeployer.

For example, to deploy the contract src/test/contracts/Constructor.huff with arguments (uint256(0x420), uint256(0x420)), you are encouraged to follow the logic defined in the deploy function of the HuffDeployerArguments contract below.

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.7.0 <0.9.0;

import {HuffDeployer} from "foundry-huff/HuffDeployer";

interface Constructor {
  function getArgOne() external returns (address);
  function getArgTwo() external returns (uint256);
}

contract HuffDeployerArguments {
  function deploy() public {
    // Deploy the contract with arguments
    address addr = HuffDeployer
      .config()
      .with_args(bytes.concat(abi.encode(uint256(0x420)), abi.encode(uint256(0x420))))
      .deploy("test/contracts/Constructor");

    // To call a function on the deployed contract, create an interface and wrap the address
    Constructor construct = Constructor(addr);

    // Validate we deployed the Constructor with the correct arguments
    assert(construct.getArgOne() == address(0x420));
    assert(construct.getArgTwo() == uint256(0x420));
  }

  function depreciated_deploy() public {
    address addr = HuffDeployer.deploy_with_args(
      "test/contracts/Constructor",
      bytes.concat(abi.encode(uint256(0x420)), abi.encode(uint256(0x420)))
    );

    // ...
  }
}

HuffDeployer also enables you to instantiate contracts, from the test file, even if they have no constructor macro!

This is possible by using Foundry's ffi cheatcode.

NOTE: It is highly recommended that you read the foundry book, or at least familiarize yourself with foundry, before using this library to avoid easily susceptible footguns.

Let's use the huff contract src/test/contracts/NoConstructor.huff, which has no defined constructor macro. The inline-instantiation defined in the deploy function of the HuffDeployerCode contract below is recommended.

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.7.0 <0.9.0;

import {HuffDeployer} from "foundry-huff/HuffDeployer";

interface Constructor {
  function getArgOne() external returns (address);
  function getArgTwo() external returns (uint256);
}

contract HuffDeployerCode {

  function deploy() public {
    // Define a new constructor macro as a string
    string memory constructor_macro = "#define macro CONSTRUCTOR() = takes(0) returns (0) {"
      "    // Copy the first argument into memory \n"
      "    0x20                        // [size] - byte size to copy \n"
      "    0x40 codesize sub           // [offset, size] - offset in the code to copy from\n "
      "    0x00                        // [mem, offset, size] - offset in memory to copy to \n"
      "    codecopy                    // [] \n"
      "    // Store the first argument in storage\n"
      "    0x00 mload                  // [arg] \n"
      "    [CONSTRUCTOR_ARG_ONE]       // [CONSTRUCTOR_ARG_ONE, arg] \n"
      "    sstore                      // [] \n"
      "    // Copy the second argument into memory \n"
      "    0x20                        // [size] - byte size to copy \n"
      "    0x20 codesize sub           // [offset, size] - offset in the code to copy from \n"
      "    0x00                        // [mem, offset, size] - offset in memory to copy to \n"
      "    codecopy                    // [] \n"
      "    // Store the second argument in storage \n"
      "    0x00 mload                  // [arg] \n"
      "    [CONSTRUCTOR_ARG_TWO]       // [CONSTRUCTOR_ARG_TWO, arg] \n"
      "    sstore                      // [] \n"
      "}";

    // Deploy the contract with arguments
    address addr = HuffDeployer
      .config()
      .with_args(bytes.concat(abi.encode(uint256(0x420)), abi.encode(uint256(0x420))))
      .with_code(constructor_macro)
      .deploy("test/contracts/NoConstructor");

    // To call a function on the deployed contract, create an interface and wrap the address
    Constructor construct = Constructor(addr);

    // Validate we deployed the Constructor with the correct arguments
    assert(construct.getArgOne() == address(0x420));
    assert(construct.getArgTwo() == uint256(0x420));
  }

  function depreciated_deploy_with_code() public {
    address addr = HuffDeployer.deploy_with_code(
      "test/contracts/Constructor",
      constructor_macro
    );

    // ...
  }
}

foundry-huff's People

Contributors

refcell avatar jetjadeja avatar devtooligan avatar ncitron avatar clabby avatar obatirou avatar maddiaa0 avatar minaminao avatar philogy avatar jameswenzel avatar 0xkitsune avatar amadimichael avatar 0xmulch avatar emo-eth avatar mw2000 avatar patrickalphac avatar sabnock01 avatar pmerkleplant 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.