
Walkthrough: Huff Challenge #4
In this article, we are going to explore the solution to the Huff Challenge 4. You can find walkthroughs for other challenges below:Challenge #1Challenge #2Challenge #3Also if you are new to huff and wanna learn how to test and deploy Huff contracts, check out this article. Alright let’s dive in.The Problem Statement:In this challenge, we're tasked with writing a Huff smart contract that reverses the calldata that it receives. Essentially, if you send data to this contract, it should be ...

Huff By Example
In this rapidly evolving landscape of blockchain technology, efficiency isn't just an advantage—it's a necessity. More the adoption is, the more congested the networks become (for now this is the case), hence the race for gas optimization intensifies, every opcode, every byte, and every operation counts. Enter Huff, a language so close to the metal of the Ethereum Virtual Machine (EVM) which has the potential to take on-chain possibilities to one step further. In this post, we’ll di...

Walkthrough: Huff Challenge #3
In this article, we are going to explore the solution to the Huff Challenge 3. You can find walkthroughs for Challenge #1 here and Challenge #2 here. If you wanna learn how to test and deploy Huff contracts, check out this article.Overview:Here’s the target contract for the challenge:#define constant OWNER_SLOT = 0x00 #define constant WITHDRAWER_SLOT = 0x01 #define constant LAST_DEPOSITER_SLOT = 0x02 // Deposit into the contract. #define macro DEPOSIT() = takes (0) returns (0) { callvalue isz...
EVM | DeFi | SmartContracts 🚀

Walkthrough: Huff Challenge #4
In this article, we are going to explore the solution to the Huff Challenge 4. You can find walkthroughs for other challenges below:Challenge #1Challenge #2Challenge #3Also if you are new to huff and wanna learn how to test and deploy Huff contracts, check out this article. Alright let’s dive in.The Problem Statement:In this challenge, we're tasked with writing a Huff smart contract that reverses the calldata that it receives. Essentially, if you send data to this contract, it should be ...

Huff By Example
In this rapidly evolving landscape of blockchain technology, efficiency isn't just an advantage—it's a necessity. More the adoption is, the more congested the networks become (for now this is the case), hence the race for gas optimization intensifies, every opcode, every byte, and every operation counts. Enter Huff, a language so close to the metal of the Ethereum Virtual Machine (EVM) which has the potential to take on-chain possibilities to one step further. In this post, we’ll di...

Walkthrough: Huff Challenge #3
In this article, we are going to explore the solution to the Huff Challenge 3. You can find walkthroughs for Challenge #1 here and Challenge #2 here. If you wanna learn how to test and deploy Huff contracts, check out this article.Overview:Here’s the target contract for the challenge:#define constant OWNER_SLOT = 0x00 #define constant WITHDRAWER_SLOT = 0x01 #define constant LAST_DEPOSITER_SLOT = 0x02 // Deposit into the contract. #define macro DEPOSIT() = takes (0) returns (0) { callvalue isz...
EVM | DeFi | SmartContracts 🚀

Subscribe to PraneshASP ⚡

Subscribe to PraneshASP ⚡
<100 subscribers
<100 subscribers
Share Dialog
Share Dialog


In this post, we will dive into the steps involved in testing and deploying a smart-contract written using the Huff programming 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 team originally created Huff to write Weierstrudel, an on-chain elliptical curve arithmetic library that requires incredibly optimized code that neither Solidity nor Yul 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 by devtooligan is a great resource. Also feel free to explore the official documentation of Huff at your own pace.
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.
#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.
We can test the above contract in 2 ways.
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 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.
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 util created by Maddiaa 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.
We can run the tests using the command:
$ huffc ./test/Math.t.huff test
The output will be something similar to the below image:

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:

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. If you want to deploy contracts with arguments, you can have a look into my Huffbound deployment script.
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
Until next time 👋👋.
In this post, we will dive into the steps involved in testing and deploying a smart-contract written using the Huff programming 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 team originally created Huff to write Weierstrudel, an on-chain elliptical curve arithmetic library that requires incredibly optimized code that neither Solidity nor Yul 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 by devtooligan is a great resource. Also feel free to explore the official documentation of Huff at your own pace.
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.
#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.
We can test the above contract in 2 ways.
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 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.
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 util created by Maddiaa 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.
We can run the tests using the command:
$ huffc ./test/Math.t.huff test
The output will be something similar to the below image:

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:

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. If you want to deploy contracts with arguments, you can have a look into my Huffbound deployment script.
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
Until next time 👋👋.
No activity yet