• Stars
    star
    196
  • Rank 198,511 (Top 4 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created almost 3 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🥘 Hassle-free Hardhat plugin to compare gas cost among different Solidity code snippets.

🥘 Marmite

version npm license stars

Hassle-free Hardhat plugin to compare gas cost among different Solidity code snippets.

Demo

🧩 Features

  • 📊 Compare code snippets directly in your contracts
  • ✅ Compatible with any Solidity versions
  • 🔍 Checks function calls and contract deployments
  • 💯 Accurate gas cost metrics using code preprocessing
  • 🧰 Supports single contracts and complex scripts

📦 Installation

First thing to do is to install the plugin in your Hardhat project:

# Using yarn
yarn add @primitivefi/hardhat-marmite

# Or using npm
npm i @primitivefi/hardhat-marmite

Next step is simply to include the plugin into your hardhat.config.js or hardhat.config.ts file:

// Using JavaScript
require('@primitivefi/hardhat-marmite');

// Using ES6 or TypeScript
import '@primitivefi/hardhat-marmite';

⛽️ Usage

Marmite offers 2 different tasks that you can use to compare gas costs:

  • golf:contract for standalone contracts and simple function calls
  • golf:script for all the more complex scenarios

In both cases, the first thing to do is always to write the different snippets that you want to compare, these are called the implementations.

✍️ Solidity implementations

Declaring an implementation is a piece of cake, just put your Solidity code within the tags @start<Name-of-your-implementation> and @end.

Let's say that you want to know if it's cheaper to check if a variable is "different from 0" or "higher than 0", simply write inside of your contract:

// SPDX-License-Identifier: WTFPL
pragma solidity 0.8.9;

contract Foo {
    uint256 public bar;

    function set(uint256 newBar) external {
        // Declaring our first implementation
        @start<Different-from>
        if (newBar != 0) {
            bar = newBar;
        }
        @end

        // Declaring our second implementation
        @start:<Greater-than>
        if (newBar > 0) {
            bar = newBar;
        }
        @end
    }
}

Marmite will know that it has to compare the gas cost of Different-from and Greater-than. Under the hood, this contract will be compiled 2 times, using each time the code of a different implementation.

📃 golf:contract

Standalone contracts and unique function calls can be quickly gas golf-ed using this task:

npx hardhat golf:contract --contract Foo --func set --params 42

golf:contract

This will tell Marmite to deploy the contract Foo and call the function set with the parameter 42. Note that since no implementation names were specified, Marmite will naively measure all of them.

Here are all the options of the golf:contract task:

  • --contract (mandatory): Name of the contract to deploy, e.g. Foo
  • --ctorParams (optional): Parameters to pass to the constructor during the contract deployment, separated by a comma, e.g. 42,true
  • --func (mandatory): Name of the function to call, e.g. set
  • --params (optional): Parameters to pass with the function call, separated by a comma, e.g. 42,true
  • --impls (optional): Name of the implementations to compare, separated by a comma, note that if this parameter is missing, all the found implementations will be compared, e.g. Different-from,Greater-than

📽 golf:script

Some more complex scenarios require a script to deploy the contracts or to set up a particular environment, this task is especially made to tackle these cases.

Scripts are very similar to the usual Hardhat tasks, scripts or fixtures, but the only difference is that all the logic must happen inside the Marmite context function:

import hre from 'hardhat';
import marmite from '@primitivefi/hardhat-marmite';

async function main() {
  await marmite(hre, async (flag) => {
    const Foo = await hre.ethers.getContractFactory('Foo');
    const foo = await Foo.deploy();

    const tx = await foo.set(42);
    await flag('set function', tx);
  });
}

main();

This example is showcasing the important steps to write a script:

  1. Import the marmite context function
  2. Pass the hre (Hardhat Runtime Environment) variable to the context function, along with a callback function deploying your contracts and executing your transactions
  3. A flag function is provided to your callback function as a parameter, use it to pin a transaction whenever you are interested in having its gas cost compared in the final results

Here is a quick API describing these two functions:

🥘 marmite

/**
 * Marmite context function
 * @param hre Hardhat Runtime Environment variable
 * @param callback Function deploying contracts and flagging transactions
 * @param implementations (optional) Array of implementation names to compare, omitting
 *                        this parameter will compare all the found implementations
 */
export default async function marmite(
  hre: HardhatRuntimeEnvironment,
  callback: CallbackFunction,
  implementations: string[] = [],
): Promise<void>

🚩 flag

/**
 * Flags a transaction to display its gas cost in the final results
 * @param name Name of the flag
 * @param tx Transaction to flag
 */
export type FlagFunction = (name: string, tx: ContractTransaction | TransactionResponse) => void;

Once your script is ready, you can run:

npx hardhat golf:script ./path/to/yourScript.ts

golf:script

This task only takes one unnamed parameter, which is the path to your script, e. g. ./examples/scripts/foo.ts.

🔧 Config

Coming soon 👀

⛑ Help

Feel free to open an issue if you need help or if you encounter a problem! Here are some already known problems though:

  • Naming a flag constructor will create a JS / TS issue
  • Compiling your contracts using npx hardhat compile might not work if Marmite tags are still present in your code

More Repositories

1

arbiter

A blazing-fast Ethereum sandbox that lets developers orchestrate event-driven simulations.
Rust
669
star
2

primitive-dodoc

☄️ Zero-config Hardhat plugin to generate documentation for all your Solidity contracts.
TypeScript
135
star
3

rmm-core

Primitive Replicating Market Maker smart contracts
Solidity
131
star
4

solstat

Math library written in solidity for statistical function approximations like the Normal Cumulative Distribution Function.
Solidity
118
star
5

portfolio

Portfolio is an automated market making protocol for implementing custom strategies at the lowest cost possible.
Solidity
113
star
6

hardhat-foundry

Forkable hardhat & foundry template for thorough evm development.
Solidity
87
star
7

soulbound

Implementation of a non-transferrable NFT using non-financial incentivization.
Solidity
85
star
8

rmms-py

Python simulator to test implementation of the RMMS paper results.
Python
55
star
9

RMM01-Simulations

RMM-01 Simulations
Python
50
star
10

arbiter-template

Minimal template for simulating contracts with arbiter.
Rust
45
star
11

v1-contracts

Primitive protocol solidity contracts.
Solidity
43
star
12

rmm-manager

Manager and Routing smart contracts for Primitive RMM
Solidity
34
star
13

univ3-kit

An open simulation for Uniswap V3 contracts
Rust
34
star
14

sybil-detection

Python
31
star
15

open-research-questions

This is a collection of open research questions in the DeFi mechanism design space pertinent to the Primitive R&D Team. This serves as a public forum and is open to discussion and changes amongst the broader DeFi research and development community.
26
star
16

excalibur

Excalibur
Rust
21
star
17

rmm-math

Typescript math library for cumulative distributions, black-scholes, and the RMM trading function.
TypeScript
21
star
18

proto-sim-portfolio

Prototype risk modeling simulation for Portfolio using Arbiter.
Rust
20
star
19

DFMM

Smart contracts of the DFMM protocol
Rust
18
star
20

rmm-ethers

Library for interacting with RMM protocol through ethers.js.
TypeScript
15
star
21

aika

Discrete event simulator built in Rust 🦀
Rust
13
star
22

Topological-Data-Analysis

This repository is for topologic and geometric data analysis.
Python
13
star
23

m3-rs

Simple rust interface to get derived analytical information of algorithmic market making models (M3).
Rust
12
star
24

portfolio_simulations

Moving to the new Arbiter framework to test Portfolio.
Rust
10
star
25

rmm-sdk

Typescript based entity classes and transaction builders for the rmm-core and rmm-periphery smart contracts.
TypeScript
10
star
26

rmm-examples

Solidity
10
star
27

portfolio-rs

SDK for the Portfolio protocol written in rust.
Rust
9
star
28

v1-connectors

Smart contracts that connect Primitive V1 to other Ethereum protocols and standards.
Solidity
9
star
29

DisputeGameSimulations

Rust
9
star
30

CFMMRouter.py

Python implementation of CFMMRouter.jl
Python
9
star
31

visualization-rs

This is a collection of math and plotting tools for us to use for visualizing data.
Rust
8
star
32

rmm-docs

Primitive and RMM Protocol Documentation - Crypto Derivatives without Counterparties
JavaScript
7
star
33

fvm.ts

TypeScript
4
star
34

pool-analytics

Jupyter Notebook
4
star
35

v1-interface

An open-source interface for the Primitive protocol.
TypeScript
4
star
36

dagger

A lightweight interface for the DFMM smart contracts
TypeScript
4
star
37

Research

Research papers and repository directory
3
star
38

v1-sdk

An SDK for the Primitive Protocol.
TypeScript
3
star
39

portfolio-ts

Minimal toolkit for building TypeScript based applications for Portfolio by Primitive.
TypeScript
3
star
40

Arbitrum-Transaction-Data-Analysis

This repository is for transaction data analysis on the the Arbitrum Network
3
star
41

amm-auction

Solidity
3
star
42

portfolio-examples-solidity

Solidity
3
star
43

arbmod

git submodule for arbiter
Solidity
3
star
44

v1-subgraph

A graph for the Primitive Protocol.
TypeScript
3
star
45

dfmm-indexer

Indexer for the DFMM protocol
TypeScript
3
star
46

security

All security reports for Primitive products and protocols.
2
star
47

discord-bot

TypeScript
2
star
48

rmm-core-dapptools

Rmm protocol core contracts in dapptools testing environment.
Solidity
2
star
49

arbiter-dispute-game

TeX
2
star
50

brand

Primitive's brand assets.
2
star
51

v1-amm-spec

Derivative focused AMM for the Primitive Protocol.
Solidity
2
star
52

arbiter-portfolio-sim

Migration from old middleware to new.
Solidity
1
star
53

rmm

Solidity
1
star
54

nugu

Solidity
1
star
55

fee-generation-py

Python
1
star