Skip to main content

OpenZeppelin Contracts for Cairo

Tests and linter

A library for secure smart contract development written in Cairo for StarkNet, a decentralized ZK Rollup.

Usage

⚠️ WARNING! ⚠️

This repo contains highly experimental code. Expect rapid iteration. Use at your own risk.

First time?

Before installing Cairo on your machine, you need to install gmp:

sudo apt install -y libgmp3-dev # linux
brew install gmp # mac

If you have any troubles installing gmp on your Apple M1 computer, here’s a list of potential solutions.

Set up your project

Create a directory for your project, then cd into it and create a Python virtual environment.

mkdir my-project
cd my-project
python3 -m venv env
source env/bin/activate

Install the Nile development environment and then run init to kickstart a new project. Nile will create the project directory structure and install the Cairo language, a local network, and a testing framework.

pip install cairo-nile
nile init

Install the library

pip install openzeppelin-cairo-contracts

Use a basic preset

Presets are ready-to-use contracts that you can deploy right away. They also serve as examples of how to use library modules. Read more about presets.

# contracts/MyToken.cairo

%lang starknet

from openzeppelin.token.erc20.presets.ERC20 import constructor

Compile and deploy it right away:

nile compile

nile deploy MyToken <name> <symbol> <decimals> <initial_supply> <recipient> --alias my_token

Note that <initial_supply> is expected to be two integers i.e. 1 0. See Uint256 for more information.

Write a custom contract using library modules

Read more about libraries.

%lang starknet

from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.uint256 import Uint256
from openzeppelin.security.pausable.library import Pausable
from openzeppelin.token.erc20.library import ERC20

(...)

@external
func transfer{
        syscall_ptr : felt*,
        pedersen_ptr : HashBuiltin*,
        range_check_ptr
    }(recipient: felt, amount: Uint256) -> (success: felt):
    Pausable.assert_not_paused()
    ERC20.transfer(recipient, amount)
    return (TRUE)
end

Learn

Documentation

Check out the full documentation site! Featuring:

Cairo

Nile

Development

Set up the project

Clone the repository

git clone git@github.com:OpenZeppelin/cairo-contracts.git

cd into it and create a Python virtual environment:

cd cairo-contracts
python3 -m venv env
source env/bin/activate

Install dependencies:

python -m pip install .

Compile the contracts

nile compile --directory src

🤖 Compiling all Cairo contracts in the src directory
🔨 Compiling src/openzeppelin/token/erc20/library.cairo
🔨 Compiling src/openzeppelin/token/erc20/presets/ERC20Mintable.cairo
🔨 Compiling src/openzeppelin/token/erc20/presets/ERC20Pausable.cairo
🔨 Compiling src/openzeppelin/token/erc20/presets/ERC20Upgradeable.cairo
🔨 Compiling src/openzeppelin/token/erc20/presets/ERC20.cairo
🔨 Compiling src/openzeppelin/token/erc20/IERC20.cairo
🔨 Compiling src/openzeppelin/token/erc721/enumerable/library.cairo
🔨 Compiling src/openzeppelin/token/erc721/library.cairo
🔨 Compiling src/openzeppelin/token/erc721/utils/ERC721Holder.cairo
🔨 Compiling src/openzeppelin/token/erc721/presets/ERC721MintablePausable.cairo
🔨 Compiling src/openzeppelin/token/erc721/presets/ERC721MintableBurnable.cairo
🔨 Compiling src/openzeppelin/token/erc721/presets/ERC721EnumerableMintableBurnable.cairo
🔨 Compiling src/openzeppelin/token/erc721/IERC721.cairo
🔨 Compiling src/openzeppelin/token/erc721/IERC721Metadata.cairo
🔨 Compiling src/openzeppelin/token/erc721/IERC721Receiver.cairo
🔨 Compiling src/openzeppelin/token/erc721/enumerable/IERC721Enumerable.cairo
🔨 Compiling src/openzeppelin/access/ownable/library.cairo
🔨 Compiling src/openzeppelin/security/reentrancyguard/library.cairo
🔨 Compiling src/openzeppelin/security/safemath/library.cairo
🔨 Compiling src/openzeppelin/security/pausable/library.cairo
🔨 Compiling src/openzeppelin/security/initializable/library.cairo
🔨 Compiling src/openzeppelin/utils/constants/library.cairo
🔨 Compiling src/openzeppelin/introspection/erc165/library.cairo
🔨 Compiling src/openzeppelin/introspection/erc165/IERC165.cairo
🔨 Compiling src/openzeppelin/upgrades/library.cairo
🔨 Compiling src/openzeppelin/upgrades/presets/Proxy.cairo
🔨 Compiling src/openzeppelin/account/library.cairo
🔨 Compiling src/openzeppelin/account/presets/EthAccount.cairo
🔨 Compiling src/openzeppelin/account/presets/Account.cairo
🔨 Compiling src/openzeppelin/account/presets/AddressRegistry.cairo
🔨 Compiling src/openzeppelin/account/IAccount.cairo
✅ Done

Run tests

Run tests using tox, tox automatically creates an isolated testing environment:

tox

====================== test session starts ======================
platform linux -- Python 3.7.2, pytest-7.1.2, py-1.11.0, pluggy-1.0.0
rootdir: /home/readme/cairo-contracts, configfile: tox.ini
plugins: asyncio-0.18.3, xdist-2.5.0, forked-1.4.0, web3-5.29.0, typeguard-2.13.3
asyncio: mode=auto
gw0 [185] / gw1 [185]
......................................................................................
......................................................................................
............    [100%]

Run Tests in Docker

For M1 users or those who are having trouble with library/python versions you can alternatively run the tests within a docker container. Using the following as a Dockerfile placed in the root directory of the project:

FROM python:3.7

RUN pip install tox
RUN mkdir cairo-contracts
COPY . cairo-contracts
WORKDIR cairo-contracts
ENTRYPOINT tox

After its placed there run:

docker build -t cairo-tests .
docker run cairo-tests

Parallel Testing

This repo utilizes the pytest-xdist plugin which runs tests in parallel. This feature increases testing speed; however, conflicts with a shared state can occur since tests do not run in order. To overcome this, independent cached versions of contracts being tested should be provisioned to each test case. Here's a simple fixture example:

from utils import get_contract_class, cached_contract

@pytest.fixture(scope='module')
def foo_factory():
    # get contract class
    foo_cls = get_contract_class('Foo')

    # deploy contract
    starknet = await Starknet.empty()
    foo = await starknet.deploy(contract_class=foo_cls)

    # copy the state and cache contract
    state = starknet.state.copy()
    cached_foo = cached_contract(state, foo_cls, foo)

    return cached_foo

See Memoization in the Utilities documentation for a more thorough example on caching contracts.

Note that this does not apply for stateless libraries such as SafeMath.

Security

⚠️ Warning! ⚠️ This project is still in a very early and experimental phase. It has never been audited nor thoroughly reviewed for security vulnerabilities. Do not use in production.

Refer to SECURITY.md for more details.

Contribute

OpenZeppelin Contracts for Cairo exists thanks to its contributors. There are many ways you can participate and help build high quality software. Check out the contribution guide!

Markdown linter

To keep the markdown files neat and easy to edit, we utilize DavidAnson's markdownlint linter. You can find the listed rules here. Note that the following rules are disabled:

  • MD013: line length

    • to enable paragraphs without internal line breaks
  • MD033: inline HTML

    • to enable .md files to have duplicate headers and separate them by identifiers

Before creating a PR, check that documentation changes are compliant with our markdown rules by running:

tox -e lint

License

OpenZeppelin Contracts for Cairo is released under the MIT License.

Metadata

Release files for imx-openzeppelin-cairo-contracts 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for imx-openzeppelin-cairo-contracts 0.5.0
File Size Uploaded Provenance Actions
imx_openzeppelin_cairo_contracts-0.5.0.tar.gz 130.5 kB Without provenance Details for imx_openzeppelin_cairo_contracts-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for imx-openzeppelin-cairo-contracts 0.5.0
File Interpreter ABI Platform Actions
imx_openzeppelin_cairo_contracts-0.5.0-py3-none-any.whl Python 3 none any Details for imx_openzeppelin_cairo_contracts-0.5.0-py3-none-any.whl

Total release size: 168.6 kB

Release files / imx_openzeppelin_cairo_contracts-0.5.0.tar.gz

Download URL imx_openzeppelin_cairo_contracts-0.5.0.tar.gz
Size 130.5 kB
Tags Source
SHA-256 checksum
How to use checksums
078371dd44c11bdf03400137ea09da6aee3318a7b15570c3f30b99839ae1c289
BLAKE2b-256 checksum
How to use checksums
056e11dca1b733098c8e98799e011e87ce59a03db74e9b5a451467b14a71fe2b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.14

Release files / imx_openzeppelin_cairo_contracts-0.5.0-py3-none-any.whl

Download URL imx_openzeppelin_cairo_contracts-0.5.0-py3-none-any.whl
Size 38.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
344508bd27fe1f2dba6a1fa703db2b73ee80ee34b64f5c24ba24c40588f064c5
BLAKE2b-256 checksum
How to use checksums
01b8169c6a121742f594e15e0181d43c690efe12f511f1dd5580c3ab11de68a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.14

Security for imx-openzeppelin-cairo-contracts 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page