Adding Dependencies to your Contracts in Foundry

In building smart contracts a very common thing you will need to do is add dependencies to take advantage of code other people have already written. One of the most common dependencies/smart contract libraries to use is OpenZeppelin's contracts. They have several security tested contracts to implement your own security or easily create your own ERC-20 tokens or ERC-721 NFT smart contracts.

There are a lot of hardhat tutorials out there that show you have to install OpenZeppelin's contract's to you project folder and then start importing them into your smart contracts to use but not many yet show how to do this in Foundry, where the steps to do this are pretty different. First lets review how you add OpenZeppelin contracts to a Hard Hat project

Hardhat is written in Javascript, and built on Node.js so it uses npm as its package manager.

So once you have a Hardhat project set up (see my post here about how to do that) you simply do this to install their contracts to your projects:

npm install @openzeppelin/contracts

When you are actually writing your smart contract you will need to have an import statement like this:

import "@openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";

Then you can effectively use OpenZeppelin's audited ERC721 contract to make your own NFT contract. Likewise any other OpenZeppelin contract can be used the same way.

Now in Foundry if you want you can actually follow these same steps and install OpenZeppelins contracts the same way because Foundry has this special feature called remappings, which re-map dependencies to be in whatever file path you want them to be. By using this Foundry can achieve Hardhat compatibility, and use the Hardhat file path structure so it can use contracts installed through NPM as dependencies just fine.

However, that isn't what this post is about, I want to share how to do things in Foundry natively.

From the Foundry Book:

Forge manages dependencies using git submodules by default, which means that it works with any GitHub repository that contains smart contracts.

Foundry provides forge install that lets us install dependencies. And as that quote mentions we are doing this by git submodules that contain smart contracts.

This is the github repo for OpenZepplin's main set of contracts: github.com/OpenZeppelin/openzeppelin-contra..

And this is the forge install command I used to install OpenZeppelin Contracts to my forge project:

forge install OpenZeppelin/openzeppelin-contracts

You'll see that's really just the github URL path (which is really also the same the git subdomain).

Once you have done this the OpenZeppelin contracts in that git repository will be downloaded to the lib folder of your Foundry project.

image.png

Lastly to actually use these in your contracts your import statement will be similar, but not the exact same:

import "openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";

The only difference is that in there is no '@' sign before the openzeppelin, like there is for the import statement for a Hardhat project. I'm not sure exactly what this is? Maybe because Hardhat is built on Javascript/Node.js? But every smart contract tutorial that uses Hardhat (which is most of them) has that '@' sign. And if you include that '@' sign in your smart contract in Foundry you are just going to get build errors when you try to build. So just remember no '@' sign on import statements in Foundry.

So that is how you can install OpenZeppelin Contracts natively to Foundry to use in your Foundry projects.