Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/pcaversaccio/snekmate

State-of-the-art, highly opinionated, hyper-optimised, and secure ๐ŸVyper smart contract building blocks.
https://github.com/pcaversaccio/snekmate

ethereum evm library security smart-contracts vyper vyper-contracts

Last synced: 3 days ago
JSON representation

State-of-the-art, highly opinionated, hyper-optimised, and secure ๐ŸVyper smart contract building blocks.

Awesome Lists containing this project

README

        

# ๐Ÿ snekmate

[![๐Ÿ•ต๏ธโ€โ™‚๏ธ Test smart contracts](https://github.com/pcaversaccio/snekmate/actions/workflows/test-contracts.yml/badge.svg)](https://github.com/pcaversaccio/snekmate/actions/workflows/test-contracts.yml)
[![License: AGPL-3.0-only](https://img.shields.io/badge/License-AGPL--3.0--only-blue)](https://www.gnu.org/licenses/agpl-3.0)
[![npm package](https://img.shields.io/npm/v/snekmate.svg?color=blue)](https://www.npmjs.com/package/snekmate)
[![PyPI package](https://img.shields.io/pypi/v/snekmate?color=blue)](https://pypi.org/project/snekmate)

**State-of-the-art**, **highly opinionated**, **hyper-optimised**, and **secure** ๐ŸVyper smart contract building blocks.

> [!WARNING]
> This is **experimental software** and is provided on an "as is" and "as available" basis. We **do not give any warranties** and **will not be liable for any losses** incurred through any use of this code base.

- [๐Ÿ“œ Contracts](#-contracts)
- [๐ŸŽ› Installation](#-installation)
- [1๏ธโƒฃ PyPI](#1๏ธโƒฃ-pypi)
- [2๏ธโƒฃ Foundry](#2๏ธโƒฃ-foundry)
- [3๏ธโƒฃ npm](#3๏ธโƒฃ-npm)
- [๐Ÿ”ง Usage](#-usage)
- [๐Ÿ‘ฉ๐Ÿผโ€โš–๏ธ Tests](#๏ธ-tests)
- [๐Ÿ‘ฎโ€โ™€๏ธ Audits](#๏ธ-audits)
- [๐Ÿ™๐Ÿผ Acknowledgements](#-acknowledgements)
- [๐Ÿซก Contributing](#-contributing)
- [๐Ÿ’ธ Donation](#-donation)
- [๐Ÿ’ข Disclaimer](#-disclaimer)

## ๐Ÿ“œ Contracts

```ml
src
โ””โ”€โ”€ snekmate
โ”œโ”€โ”€ auth
โ”‚ โ”œโ”€โ”€ ownable โ€” "Owner-Based Access Control Functions"
โ”‚ โ”œโ”€โ”€ ownable_2step โ€” "2-Step Ownership Transfer Functions"
โ”‚ โ”œโ”€โ”€ access_control โ€” "Multi-Role-Based Access Control Functions"
โ”‚ โ”œโ”€โ”€ interfaces
โ”‚ โ”‚ โ””โ”€โ”€ IAccessControl โ€” "AccessControl Interface Definition"
โ”‚ โ””โ”€โ”€ mocks
โ”‚ โ”œโ”€โ”€ ownable_mock โ€” "`ownable` Module Reference Implementation"
โ”‚ โ”œโ”€โ”€ ownable_2step_mock โ€” "`ownable_2step` Module Reference Implementation"
โ”‚ โ””โ”€โ”€ access_control_mock โ€” "`access_control` Module Reference Implementation"
โ”œโ”€โ”€ extensions
โ”‚ โ”œโ”€โ”€ erc2981 โ€” "ERC-721 and ERC-1155 Compatible ERC-2981 Reference Implementation"
โ”‚ โ”œโ”€โ”€ erc4626 โ€” "Modern and Gas-Efficient ERC-4626 Tokenised Vault Implementation"
โ”‚ โ”œโ”€โ”€ interfaces
โ”‚ โ”‚ โ””โ”€โ”€ IERC2981 โ€” "EIP-2981 Interface Definition"
โ”‚ โ””โ”€โ”€ mocks
โ”‚ โ”œโ”€โ”€ erc2981_mock โ€” "`erc2981` Module Reference Implementation"
โ”‚ โ””โ”€โ”€ erc4626_mock โ€” "`erc4626` Module Reference Implementation"
โ”œโ”€โ”€ governance
โ”‚ โ”œโ”€โ”€ timelock_controller โ€” "Multi-Role-Based Timelock Controller Reference Implementation"
โ”‚ โ””โ”€โ”€ mocks
โ”‚ โ””โ”€โ”€ timelock_controller_mock โ€” "`timelock_controller` Module Reference Implementation"
โ”œโ”€โ”€ tokens
โ”‚ โ”œโ”€โ”€ erc20 โ€” "Modern and Gas-Efficient ERC-20 + EIP-2612 Implementation"
โ”‚ โ”œโ”€โ”€ erc721 โ€” "Modern and Gas-Efficient ERC-721 + EIP-4494 Implementation"
โ”‚ โ”œโ”€โ”€ erc1155 โ€” "Modern and Gas-Efficient ERC-1155 Implementation"
โ”‚ โ”œโ”€โ”€ interfaces
โ”‚ โ”‚ โ”œโ”€โ”€ IERC20Permit โ€” "EIP-2612 Interface Definition"
โ”‚ โ”‚ โ”œโ”€โ”€ IERC721Enumerable โ€” "EIP-721 Optional Enumeration Interface Definition"
โ”‚ โ”‚ โ”œโ”€โ”€ IERC721Metadata โ€” "EIP-721 Optional Metadata Interface Definition"
โ”‚ โ”‚ โ”œโ”€โ”€ IERC721Permit โ€” "EIP-4494 Interface Definition"
โ”‚ โ”‚ โ”œโ”€โ”€ IERC721Receiver โ€” "EIP-721 Token Receiver Interface Definition"
โ”‚ โ”‚ โ”œโ”€โ”€ IERC1155 โ€” "EIP-1155 Interface Definition"
โ”‚ โ”‚ โ”œโ”€โ”€ IERC1155MetadataURI โ€” "EIP-1155 Optional Metadata Interface Definition"
โ”‚ โ”‚ โ”œโ”€โ”€ IERC1155Receiver โ€” "EIP-1155 Token Receiver Interface Definition"
โ”‚ โ”‚ โ””โ”€โ”€ IERC4906 โ€” "EIP-4906 Interface Definition"
โ”‚ โ””โ”€โ”€ mocks
โ”‚ โ”œโ”€โ”€ erc20_mock โ€” "`erc20` Module Reference Implementation"
โ”‚ โ”œโ”€โ”€ erc721_mock โ€” "`erc721` Module Reference Implementation"
โ”‚ โ””โ”€โ”€ erc1155_mock โ€” "`erc1155` Module Reference Implementation"
โ””โ”€โ”€ utils
โ”œโ”€โ”€ base64 โ€” "Base64 Encoding and Decoding Functions"
โ”œโ”€โ”€ batch_distributor โ€” "Batch Sending Both Native and ERC-20 Tokens"
โ”œโ”€โ”€ create_address โ€” "`CREATE` EVM Opcode Utility Function for Address Calculation"
โ”œโ”€โ”€ create2_address โ€” "`CREATE2` EVM Opcode Utility Functions for Address Calculations"
โ”œโ”€โ”€ ecdsa โ€” "Elliptic Curve Digital Signature Algorithm (ECDSA) Secp256k1-Based Functions"
โ”œโ”€โ”€ p256 โ€” "Elliptic Curve Digital Signature Algorithm (ECDSA) Secp256r1-Based Functions"
โ”œโ”€โ”€ message_hash_utils โ€” "Signature Message Hash Utility Functions"
โ”œโ”€โ”€ signature_checker โ€” "ECDSA and EIP-1271 Signature Verification Functions"
โ”œโ”€โ”€ eip712_domain_separator โ€” "EIP-712 Domain Separator"
โ”œโ”€โ”€ math โ€” "Standard Mathematical Utility Functions"
โ”œโ”€โ”€ merkle_proof_verification โ€” "Merkle Tree Proof Verification Functions"
โ”œโ”€โ”€ multicall โ€” "Multicall Functions"
โ”œโ”€โ”€ interfaces
โ”‚ โ”œโ”€โ”€ IERC1271 โ€” "EIP-1271 Interface Definition"
โ”‚ โ””โ”€โ”€ IERC5267 โ€” "EIP-5267 Interface Definition"
โ””โ”€โ”€ mocks
โ”œโ”€โ”€ base64_mock โ€” "`base64` Module Reference Implementation"
โ”œโ”€โ”€ batch_distributor_mock โ€” "`batch_distributor` Module Reference Implementation"
โ”œโ”€โ”€ create_address_mock โ€” "`create_address` Module Reference Implementation"
โ”œโ”€โ”€ create2_address_mock โ€” "`create2_address` Module Reference Implementation"
โ”œโ”€โ”€ ecdsa_mock โ€” "`ecdsa` Module Reference Implementation"
โ”œโ”€โ”€ p256_mock โ€” "`p256` Module Reference Implementation"
โ”œโ”€โ”€ message_hash_utils_mock โ€” "`message_hash_utils` Module Reference Implementation"
โ”œโ”€โ”€ signature_checker_mock โ€” "`signature_checker` Module Reference Implementation"
โ”œโ”€โ”€ eip712_domain_separator_mock โ€” "`eip712_domain_separator` Module Reference Implementation"
โ”œโ”€โ”€ math_mock โ€” "`math` Module Reference Implementation"
โ”œโ”€โ”€ merkle_proof_verification_mock โ€” "`merkle_proof_verification` Module Reference Implementation"
โ””โ”€โ”€ multicall_mock โ€” "`multicall` Module Reference Implementation"
```

## ๐ŸŽ› Installation

> [!IMPORTANT]
> ๐Ÿ snekmate uses a [ZeroVer](https://0ver.org)-based versioning scheme. This means ๐Ÿ snekmate's major version will never exceed the first and most important number in computing: zero.

We offer three convenient ways to install the ๐Ÿ snekmate contracts:

### 1๏ธโƒฃ PyPI

You can install ๐Ÿ snekmate from [PyPI](https://pypi.org/project/snekmate) with:

```console
pip install snekmate
```

> When using the ๐ŸVyper CLI, the search path [defaults](https://docs.vyperlang.org/en/latest/structure-of-a-contract.html#searching-for-imports) to the current working directory and the Python [`sys.path`](https://docs.python.org/3.13/library/sys.html#sys.path). As a result, all imported ๐Ÿ snekmate contracts (e.g. `from snekmate.tokens import erc20`) are seamlessly located during compilation.

### 2๏ธโƒฃ Foundry

You can install ๐Ÿ snekmate via submodules using [Foundry](https://github.com/foundry-rs/foundry) with:

```console
forge install pcaversaccio/snekmate
```

> [!NOTE]
> If you want to leverage ๐Ÿ snekmate's [`VyperDeployer`](./lib/utils/VyperDeployer.sol) contract for your own testing, ensure that you compile the ๐ŸVyper contracts with the same EVM version as configured in your `foundry.toml` file. The [`VyperDeployer`](./lib/utils/VyperDeployer.sol) contract offers two overloaded `deployContract` functions that allow the configuration of the target EVM version. Please note that since ๐ŸVyper version [`0.4.0`](https://github.com/vyperlang/vyper/releases/tag/v0.4.0) the default EVM version is set to `cancun`. Furthermore, the [`VyperDeployer`](./lib/utils/VyperDeployer.sol) contract relies on the Python script [`compile.py`](./lib/utils/compile.py) for successful compilation and deployment. Always use the [`VyperDeployer`](./lib/utils/VyperDeployer.sol) contract alongside with the aforementioned script.

### 3๏ธโƒฃ npm

You can install ๐Ÿ snekmate from [npm](https://www.npmjs.com/package/snekmate) with:

```console
npm install --save-dev snekmate
```

Or if you are using [Yarn](https://yarnpkg.com):

```console
yarn add --dev snekmate
```

In case you are using [pnpm](https://pnpm.io), invoke:

```console
pnpm add --save-dev snekmate
```

> [!CAUTION]
> It is possible to install the latest versions of `main` or any other branch locally via `pip install git+https://github.com/pcaversaccio/snekmate.git@` or `forge install pcaversaccio/snekmate && forge update`. Each branch, **including the `main` branch**, must be understood as a development branch that should be avoided in favour of tagged releases. The release process includes security measures that the repository branches do not guarantee.

## ๐Ÿ”ง Usage

๐ŸVyper favours code reuse through composition rather than inheritance (Solidity inheritance makes it easy to break the [Liskov Substitution Principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle)). A ๐ŸVyper module encapsulates everything required for code reuse, from type and function declarations to state. **All ๐Ÿ snekmate contracts are ๐ŸVyper modules.** Thus, many of the ๐Ÿ snekmate contracts do not compile independently, but you must `import` and `initializes` them. Please note that if a module is _stateless_, it does not require the keyword `initializes` (or `uses`) for initialisation (or usage). Each module contract has an associated mock contract in the `mock/` directory, which is part of the associated contract subdirectory. These mock contracts are very illustrative of how ๐Ÿ snekmate contracts can be used as ๐ŸVyper modules.

> [!IMPORTANT]
> All ๐Ÿ snekmate contracts are very well documented in the form of general code and [NatSpec](https://docs.vyperlang.org/en/latest/natspec.html) comments. There are no shortcuts โ€“ if you are importing specific logic, read the documentation!

Please read [here](https://docs.vyperlang.org/en/latest/using-modules.html) to learn more about using ๐ŸVyper modules.

## ๐Ÿ‘ฉ๐Ÿผโ€โš–๏ธ Tests

This repository contains [Foundry](https://github.com/foundry-rs/foundry)-based unit tests, property-based tests (i.e. stateless fuzzing), and invariant tests (i.e. stateful fuzzing) for all contracts, if applicable. All tests are run as part of the CI pipeline [`test-contracts`](./.github/workflows/test-contracts.yml).

> [!NOTE]
> An _invariant_ is a property of a program that should always hold true. Fuzzing is a way of checking whether the invariant is falsifiable.

| **Contract** | **Unit Tests** | **Property-Based Tests** | **Invariant Tests** |
| :-------------------------- | :------------: | :----------------------: | :-----------------: |
| `ownable` | โœ… | โœ… | โœ… |
| `ownable_2step` | โœ… | โœ… | โœ… |
| `access_control` | โœ… | โœ… | โœ… |
| `erc2981` | โœ… | โœ… | โœ… |
| `erc4626` | โœ… | โœ… | โœ… |
| `timelock_controller` | โœ… | โœ… | โœ… |
| `erc20` | โœ… | โœ… | โœ… |
| `erc721` | โœ… | โœ… | โœ… |
| `erc1155` | โœ… | โœ… | โœ… |
| `base64` | โœ… | โŒ | โŒ |
| `batch_distributor` | โœ… | โœ… | โœ… |
| `create_address` | โœ… | โœ… | โŒ |
| `create2_address` | โœ… | โœ… | โŒ |
| `ecdsa` | โœ… | โœ… | โŒ |
| `p256` | โœ… | โœ… | โŒ |
| `message_hash_utils` | โœ… | โœ… | โŒ |
| `signature_checker` | โœ… | โœ… | โŒ |
| `eip712_domain_separator` | โœ… | โœ… | โŒ |
| `math` | โœ… | โœ… | โŒ |
| `merkle_proof_verification` | โœ… | โœ… | โŒ |
| `multicall` | โœ… | โŒ | โŒ |

โœ… Test Type Implemented โ€ƒ โŒ Test Type Not Implemented

Furthermore, the [`echidna`](https://github.com/crytic/echidna)-based [property](https://github.com/crytic/properties) tests for the [`erc20`](./src/snekmate/tokens/ERC20.vy) and [`erc721`](./src/snekmate/tokens/ERC721.vy) contracts are available in the [`test/tokens/echidna/`](./test/tokens/echidna) directory. You can run the tests by invoking:

```console
# Run Echidna ERC-20 property tests.
~$ FOUNDRY_PROFILE=echidna echidna test/tokens/echidna/ERC20Properties.sol --contract CryticERC20ExternalHarness --config test/echidna.yaml

# Run Echidna ERC-721 property tests.
~$ FOUNDRY_PROFILE=echidna echidna test/tokens/echidna/ERC721Properties.sol --contract CryticERC721ExternalHarness --config test/echidna.yaml
```

Eventually, the [`halmos`](https://github.com/a16z/halmos)-based symbolic tests for the [`erc20`](./src/snekmate/tokens/erc20.vy), [`erc721`](./src/snekmate/tokens/erc721.vy), [`erc1155`](./src/snekmate/tokens/erc1155.vy), and [`math`](./src/snekmate/utils/math.vy) contracts are available in the [`test/tokens/halmos/`](./test/tokens/halmos) and [`test/utils/halmos/`](./test/utils/halmos) directories. You can run the tests by invoking:

> [!IMPORTANT]
> You must install the [Yices 2 SMT solver](https://github.com/SRI-CSL/yices2) before invoking the [`halmos`](https://github.com/a16z/halmos)-based symbolic tests.

```console
# Run Halmos ERC-20 symbolic tests.
~$ FOUNDRY_PROFILE=halmos halmos --contract ERC20TestHalmos --config test/halmos.toml

# Run Halmos ERC-721 symbolic tests. Be careful, this is a (very!) time-consuming operation.
~$ FOUNDRY_PROFILE=halmos halmos --contract ERC721TestHalmos --config test/halmos.toml

# Run Halmos ERC-1155 symbolic tests. Be careful, this is a (very!) time-consuming operation.
~$ FOUNDRY_PROFILE=halmos halmos --contract ERC1155TestHalmos --config test/halmos.toml

# Run Halmos math symbolic tests.
~$ FOUNDRY_PROFILE=halmos halmos --contract MathTestHalmos --config test/halmos.toml
```

> [!TIP]
> If you encounter any issues, please ensure that you have the [latest](https://github.com/vyperlang/vyper/releases) ๐ŸVyper version installed locally.

## ๐Ÿ‘ฎโ€โ™€๏ธ Audits

Although the ๐Ÿ snekmate contracts have not (yet) undergone a full comprehensive audit, selected library modules integrated into specific protocols (such as Curve) have been thoroughly reviewed within the scope of prior audits. The corresponding audit reports are available [here](./audits).

## ๐Ÿ™๐Ÿผ Acknowledgements

This repository is inspired by or directly modified from many sources, primarily:

- [ApeAcademy](https://github.com/ApeAcademy)
- [Batch Distributor](https://github.com/pcaversaccio/batch-distributor)
- [`CREATE` Factory](https://github.com/pcaversaccio/create-util)
- [Disperse Research](https://github.com/banteg/disperse-research)
- [Multicall](https://github.com/mds1/multicall)
- [OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts)
- [Solady](https://github.com/Vectorized/solady)
- [Solmate](https://github.com/transmissions11/solmate)

## ๐Ÿซก Contributing

๐Ÿ snekmate only exists thanks to its [contributors](https://github.com/pcaversaccio/snekmate/graphs/contributors). There are many ways to get involved and contribute to our high-quality and secure smart contracts. Check out our [Contribution Guidelines](./CONTRIBUTING.md)!

## ๐Ÿ’ธ Donation

I am a strong advocate of the open-source and free software paradigm. However, if you feel my work deserves a donation, you can send it to this address: [`0xe9Fa0c8B5d7F79DeC36D3F448B1Ac4cEdedE4e69`](https://etherscan.io/address/0xe9Fa0c8B5d7F79DeC36D3F448B1Ac4cEdedE4e69). I can pledge that I will use this money to help fix more existing challenges in the Ethereum ecosystem ๐Ÿค.

## ๐Ÿ’ข Disclaimer