Skip to content

RedDuck-Software/Vesting

Repository files navigation

Vesting Contract Examples

CI License: MIT Solidity Hardhat

Three different implementations of a token vesting (airdrop-style claim) contract, each demonstrating a different pattern for authorizing claims. This repository accompanies the article Vesting contract implemented in 3 different ways.

The three approaches

Contract Allocation stored Vesting gas cost Claim verification
DefaultVesting On-chain, per address Grows with the number of recipients Simple mapping lookup
MerkleVesting Off-chain, only the Merkle root on-chain One storage write regardless of recipients Merkle proof supplied by the claimer
SignatureVesting Off-chain, nothing written on vest Zero — no vesting transaction at all ECDSA signature issued by the owner

DefaultVesting is the straightforward approach: the owner writes each recipient's claimable amount into contract storage, and recipients withdraw against their balance. Simple and fully on-chain, but the owner pays gas for every recipient.

MerkleVesting moves the allocation table off-chain. The owner builds a Merkle tree of (address, amount) leaves and publishes only the root. A recipient claims by presenting their amount plus a Merkle proof. Storage cost is constant no matter how many recipients there are.

SignatureVesting removes the vesting transaction entirely. The owner signs a message binding (recipient, amount, nonce, contract address) off-chain and hands the signature to the recipient, who submits it with their claim. The contract recovers the signer and checks it is the owner.

Each pattern trades gas costs against operational complexity — the article walks through the pros and cons in detail.

Project structure

contracts/
  DefaultVesting.sol     # storage-based vesting
  MerkleVesting.sol      # Merkle-proof vesting
  SignatureVesting.sol   # ECDSA-signature vesting
  DefaultERC20.sol       # minimal ERC-20 used in tests
test/
  DefaultVesting.ts
  MerkleVesting.ts       # includes Merkle tree construction with merkletreejs
  SignatureVesting.ts    # includes off-chain message signing

Getting started

Requires Node.js 18 or newer.

npm install
npm run compile
npm test

Other useful commands:

npm run coverage   # solidity-coverage report
npm run lint       # solhint + eslint
REPORT_GAS=1 npm test   # gas usage per method

Deploying to a testnet

Copy .env.example to .env and fill in your RPC URL, private key, and (optionally) an Etherscan API key:

cp .env.example .env

The Hardhat config includes a sepolia network entry; deploy scripts are left as an exercise — the contracts take a single constructor argument, the address of the ERC-20 token being vested.

Disclaimer

These contracts are educational examples written to illustrate the trade-offs between the three patterns. They are intentionally minimal, have not been audited, and are not suitable for production use as-is.

License

MIT

About

Token vesting contract implemented 3 ways — on-chain storage, Merkle proofs, and ECDSA signatures. Hardhat template with tests comparing gas trade-offs.

Resources

License

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors