# Testing and deploying Huff contracts

By [PraneshASP ⚡](https://paragraph.com/@praneshasp) · 2023-02-11

---

In this post, we will dive into the steps involved in testing and deploying a smart-contract written using the [Huff programming](https://docs.huff.sh) language.

For those who don’t know:

> _Huff is a low-level programming language designed for developing highly optimized smart contracts that run on the Ethereum Virtual Machine (EVM). Huff does not hide the inner workings of the EVM and instead exposes its programming stack to the developer for manual manipulation._
> 
> _The_ [_Aztec Protocol_](https://aztec.network/) _team originally created Huff to write_ [_Weierstrudel_](https://github.com/aztecprotocol/weierstrudel/tree/master/huff_modules)_, an on-chain elliptical curve arithmetic library that requires incredibly optimized code that neither_ [_Solidity_](https://docs.soliditylang.org/) _nor_ [_Yul_](https://docs.soliditylang.org/en/latest/yul.html) _could provide._

Note that this post is neither an introduction to Huff nor a step-by-step tutorial.This post aims to help the beginners to quickly get started with testing and deployment of their Huff contracts. If you are new to Huff, [this video](https://www.youtube.com/watch?v=Rfaabjj7n9k) by [devtooligan](https://twitter.com/devtooligan) is a great resource. Also feel free to explore the [official documentation of Huff](https://docs.huff.sh) at your own pace.

### The Math Contract:

We are going to use a simple huff contract that performs basic math operations like add, subtract, multiply, etc.,

Note that the code below is not a complete Huff contract. It just contains the logic. The function dispatcher and other parts are contained in the wrapper. You can view the wrapper [here](https://github.com/PraneshASP/huff-math/blob/main/src/wrappers/MathWrapper.huff).

    #define macro ADD_NUMBERS() = takes (2) returns (1) {
        // Input stack:      // [num2, num1]
        add                  // [num2 + num1]         
    }
    
    #define macro SUB_NUMBERS() = takes (2) returns (1) {
        // Input stack:      // [num2, num1]
        swap1                // [num1, num2]
        sub                  // [num1 - num2]         
    }
    
    
    #define macro MULTIPLY_NUMBERS() = takes (2) returns (1) {
        // Input stack:      // [num2, num1]
        mul                  // [num2 * num1]         
    }
    
    #define macro DIVIDE_NUMBERS() = takes (2) returns (1) {
        // Input stack:      // [num2, num1]
        swap1                // [num1, num2]
        div                  // [num1 / num2]         
    }
    
    
    #define macro ABS() = takes (2) returns (1) {
        // Input stack:     // [num2, num1]
        dup1
        dup3
        lt 
        iszero swapAndSubtract jumpi
        sub                      
        complete jump  
    
        swapAndSubtract:
            swap1
            sub
        
        complete:
    }
    

_The above implementation is very basic and as always there is a plenty of room for improvements. But that’s a topic for another day._

Testing the contract:
---------------------

We can test the above contract in 2 ways.

### Using Foundry:

To test the above logic using foundry, we need to deploy the wrapper contract since it is the one that exposes the functions. Also we need to use `HuffDeployer` helper contract from the [foundry-huff](https://github.com/huff-language/foundry-huff) library.

Here’s how the tests should be setup:

*   Define the interface of the contract (`IMath`).
    
*   Deploy the wrapper contract (in the `setUp()`method) using the `HuffDeployer`.
    
*   Cast the returned address to the `IMath` interface.
    
*   Write tests as usual.
    

    /// Import HuffDeployer
    import {HuffDeployer} from "foundry-huff/HuffDeployer.sol";
    
    contract MathTest is Test {
        IMath public math;
    
        function setUp() public {
            address addr = HuffDeployer.deploy(
                "../test/foundry/wrappers/MathWrapper"
            );
            math = IMath(addr);
        }
    
        function testAddNumbers() public {
            uint256 result = math.addNumbers(420, 69);
            assertEq(result, 489);
        }
    
        function testAddNumbers_fuzz(uint256 a, uint256 b) public {
            unchecked {
                uint256 c = a + b;
    
                if (c > MAX) {
                    vm.expectRevert();
                    math.addNumbers(a, b);
                    return;
                }
    
                uint256 result = math.addNumbers(a, b);
                assertEq(result, a + b);
            }
        }
    
        function testSubNumbers() public {
            uint256 result = math.subNumbers(420, 69);
            assertEq(result, 351);
        }
    
    ...
    ...
    
    }
    

You can view all the foundry tests [here in the repo](https://github.com/PraneshASP/huff-math/blob/main/test/foundry/Math.t.sol).

### Huff Tests:

Testing Huff contracts using Foundry is the most commonly used method. But we can also write simpler (and faster) unit tests using Huff itself. The huff compiler (`huffc`) has a `test` command, which takes in the filename as an argument which contains the tests. We can use the [TestHelpers](https://github.com/cheethas/huff-vrgda/blob/main/src/utils/testHelpers.huff) util created by [Maddiaa](https://twitter.com/Maddiaa0) for basic operations like `ASSERT` , etc.,

A sample Huff test contract will look like:

    // ./test/huff/Math.t.huff
    
    /* Imports */
    #include "./helpers/TestHelpers.huff"
    #include "../../src/Math.huff"
    
    /* Tests */
    #define test TEST_ADD() = {
        0x01                // [1]
        0x02                // [2,1]
        ADD_NUMBERS()       // [sum]
        0x03                // [3,sum]
        ASSERT_EQ()         // [3 == sum]
        
        0x4563918244f40000  // [5e18]            
        0x4563918244f40000  // [5e18, 5e18]            
        ADD_NUMBERS()       // [SUM]    
        0x8ac7230489e80000  // [10e18, SUM]             
        ASSERT_EQ()         // [10e18==SUM]     
    }
    ...
    ...
    

> _Complete test file_ [_here_](https://github.com/PraneshASP/huff-math/blob/main/test/huff/Math.t.huff)_._

We can run the tests using the command:

`$ huffc ./test/Math.t.huff test`

The output will be something similar to the below image:

![Huff Test Result](https://storage.googleapis.com/papyrus_images/818bf029f9e886748b0503101d2393a3c419d6ac463832b09d690d734841f9fe.png)

Huff Test Result

* * *

Deploying Huff contracts:
-------------------------

We just saw how to test Huff contracts using Foundry and Huff. Now we can move on to the next step which is deploying the Huff contract to a EVM-based blockchain (`Goerli` , in this case). Here’s the foundry script to deploy the \`MathWrapper contract.

    // scripts/DeployMath.s.sol
    
    // SPDX-License-Identifier: Unlicense
    pragma solidity ^0.8.15;
    
    import "foundry-huff/HuffDeployer.sol";
    import "forge-std/Script.sol";
    
    import {IMath} from "../src/interfaces/IMath.sol";
    
    contract Deploy is Script {
      function run() public returns (IMath math) {
        math = IMath(HuffDeployer.broadcast("wrappers/MathWrapper"));
        console2.log("MathWrapper contract deployed to: ", address(math));
        }
    }
    

The above script can be executed by running the following command:

    $ source .env && forge script scripts/DeployMath.s.sol:DeployMath --fork-url $RPC_URL --private-key $PRIVATE_KEY --broadcast
    

_You need to configure the_ `RPC_URL` _of the network and_ `PRIVATE_KEY` _of the deployer in the_ `.env` _file._

If everything works as intended, you’ll be seeing an output something like this:

![Deployment Result](https://storage.googleapis.com/papyrus_images/dd3198a104729cbecceab16bc2bcbaaae7f5584133664141c1bb9a195c2277cd.png)

Deployment Result

To validate the deployment you can either add assertions in the script’s `run()` method or you can also implement fork tests with the deployed contract address similar to [this one](https://github.com/PraneshASP/huff-math/blob/main/test/foundry/MathForkTest.t.sol). If you want to deploy contracts with arguments, you can have a look into my [Huffbound deployment script](https://github.com/PraneshASP/huffbound/blob/main/scripts/Deploy.s.sol).

* * *

Sweet. We have successfully tested and deployed our simple `Math.huff` contract. You can follow the same process to test and deploy more complex Huff contracts as well.

_Here’s the link to GitHub repo:_

[https://github.com/PraneshASP/huff-math/tree/main/src](https://github.com/PraneshASP/huff-math/tree/main/src)

Until next time 👋👋.

---

*Originally published on [PraneshASP ⚡](https://paragraph.com/@praneshasp/testing-and-deploying-huff-contracts)*
