Skip to content

About

πŸ” Solidity smart contracts for Locker Protocol β€” ERC-20 token locking with multi-signature (M-of-N) governance, EIP-712 air-gapped signing, on-chain price oracles (Uniswap V2/V3), vesting schedules, and 1-click deployment registry. Deployed on Ethereum, ready for 9 EVM chains.

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Locker Protocol β€” Smart Contracts

Tests Slither License Solidity Hardhat Node Multi-Chain

Non-custodial ERC-20 token locking with multi-signature governance, air-gapped signing (EIP-712 + QR codes), on-chain price conditions, and progressive vesting.

Deploy your own Locker smart contracts on any EVM chain and register them on lockerprotocol.com.


Table of Contents

  1. Overview
  2. Architecture
  3. Smart Contracts
  4. Quick Start
  5. Testing
  6. Deploy on Mainnet
  7. Register on Locker Protocol
  8. Supported Chains
  9. Security
  10. License

Overview

Locker Protocol allows any entity to deploy its own vault infrastructure using a modular smart contract architecture. A group of signers (3 to 20) manages locked assets via multi-signature (M-of-N) logic with offline signing support (EIP-712 + QR codes).

Key Features

  • Multi-Signature Security β€” M-of-N threshold signing, 1 to 20 signers
  • Air-Gapped Signing β€” Sign transactions offline via EIP-712 + animated QR codes
  • Flexible Lock Conditions β€” Time-based, price-based (Uniswap V2/V3 oracle), or both
  • Progressive Vesting β€” Token-denominated or percentage schedules (optional accumulation)
  • Replay Protection β€” Per-operation nonces prevent signature reuse
  • Symmetric Authority β€” Immobilising funds costs the same quorum as releasing them
  • Chain-Aware Asset Registries β€” Canonical stablecoin/WETH sets keyed by chain id
  • Launch Suite β€” Stablecoin-only presale and allocation rounds with on-chain raise-lock proofs
  • Multi-Chain β€” Deploy on Ethereum, BSC, Polygon, Arbitrum, Base, and more

Architecture

graph TD
    subgraph "Your Deployment"
        LC["LockerContract<br/>(Entry Point)"]
        LM["LockManager<br/>(Lock Storage & Conditions)"]
        SM["SignerManager<br/>(Authorized Signers)"]
        VH["ValidationHandler<br/>(EIP-712 Multi-Sig Engine)"]
        VM["VestingManager<br/>(Progressive Release)"]
        PC["PriceCalculator<br/>(Uniswap V2/V3 Oracle)"]
    end

    subgraph "Launch Suite (optional)"
        LF["LaunchFactory<br/>(Canonical Rails per Chain)"]
        PR["PresaleRound<br/>(Stablecoin-Only Sale)"]
        AR["AllocationRound<br/>(Merkle Distribution)"]
    end

    subgraph "Locker Protocol Platform"
        UI["lockerprotocol.com<br/>(Management UI)"]
    end

    LC --> LM
    LC --> SM
    LC --> VH
    LC --> VM
    LM --> PC
    VM --> PC
    UI -->|"Add Custom Locker"| LC

    LF -->|"deploys"| PR
    LF -->|"deploys"| AR
    PR -->|"codehash check + raise-lock"| LC
Loading

The Launch Suite is optional: a Locker deployment is complete and fully usable without it. When used, a PresaleRound proves its "the raise is locked" claim by pointing at a lock inside the team's own LockerContract, and the factory verifies that locker is genuine before the round can be created.


Smart Contracts

All contracts use Solidity ^0.8.20 with OpenZeppelin primitives.

Contract Role
LockerContract Central entry point - delegates to all modules, manages nonces
LockManager Lock storage, time/price condition evaluation, token accounting
SignerManager Authorized signer list, M-of-N threshold management
ValidationHandler Multi-sig engine, EIP-712 signature verification via ecrecover
VestingManager Progressive token release with token-denominated schedules
PriceCalculator On-chain price oracle - queries Uniswap V2 reserves and V3 slots
FullMath Safe math library for price calculations

Launch Suite (optional)

Contract Role
LaunchFactory Per-chain source of truth - holds the canonical rails, deploys rounds
PresaleRound Stablecoin-only sale with tranches, refunds, and a verified raise-lock
AllocationRound Merkle-based allocation and claiming
LaunchVestingCore Shared vesting maths for both round types
LaunchRoundDeployers Split deployers - keeps the factory under the EIP-170 size limit

Supporting Libraries

File Role
LockerContractStructs.sol Shared data structures (CreateLockParams, SignatureParams)
LockerInternal.sol Internal logic (operation validation, batch approve)
LockerLockOperations.sol Lock/unlock operations with signature verification
LockerSignerOperations.sol Threshold update with multi-sig
LockerViewFunctions.sol Read-only view functions

Mock Contracts (Testing Only)

All mocks live in contracts/mocks/ and are never deployed to a real network.

Contract Usage
ERC20Mock Standard ERC-20 token for testing
ERC20MockWithDecimals ERC-20 with custom decimals
ERC20MutableDecimals Token that changes decimals() between calls
ERC20USDTMock USDT simulation (non-standard approve)
ERC20FeeMock Fee-on-transfer token, including a fee switched on mid-flight
ERC20Blacklistable USDC/USDT-style blacklist and pause switches
MockUniswapV2Pair Uniswap V2 pool simulation
MockUniswapV3Pool Uniswap V3 pool simulation
MockBrokenPool Pool returning malformed or zero-liquidity data
MockAggregatorV3 Chainlink-style feed (legacy oracle paths)
WETH9Mock Wrapped-native mock
FullMathMock Direct harness for the FullMath library
ForceSend Forces native coin into a contract with no receive()
ReentrantUnlockToken Reentrancy attempt on the unlock path
ReentrantPresaleAttacker Reentrancy attempt on presale refunds
RogueTeamLocker Hand-written locker impostor (wrong codehash)
FakeLocker Locker-shaped contract failing the consistency probe
FakeVestingManagerForAnchor Canonical-shell locker wired to a hostile VestingManager
PermissiveSignerManagerMock SignerManager that approves everything
AliasedStableForRescue Token aliasing a canonical stablecoin address
ForwardingBeneficiary Beneficiary that forwards value on receipt

Quick Start

Prerequisites

Tool Version Check
Node.js 22+ (see .nvmrc) node --version
NVM Latest nvm --version
Git Latest git --version

Install & Compile

# Clone the repository
git clone https://github.com/locker-protocol/locker-protocol-smart-contracts.git
cd locker-smart-contracts

# Use the correct Node version
nvm use

# Install dependencies
npm install

# Compile contracts
npx hardhat compile

Deploy Locally (for testing)

# Terminal 1: Start a local Hardhat node
npx hardhat node

# Terminal 2: Deploy all contracts
npx hardhat run scripts/deploy-local.js --network localhost

This deploys:

  • All 6 core contracts (LockerContract, LockManager, SignerManager, ValidationHandler, VestingManager, PriceCalculator)
  • Mock ERC-20 tokens (WETH, USDT, USDC, DAI)

Deployed addresses are saved to deployed-addresses.json.


Testing

Tests

The test suite contains 91 test files covering all contract functionality - from core locking and vesting to multi-signature governance, replay protection, the Launch Suite, and adversarial security scenarios.

A large share of them are adversarial: they mount a concrete attack and pass only when it is blocked. Green there means "the hole is closed", not "the feature works" - each one fails loudly (ATTACK SUCCEEDED) while its hole is open, so it stays the regression test for its own fix.

Tests run on a local Hardhat node with automated setup, compilation, and teardown.

# Run all tests
npm test

# Run a specific test
cd test
./run_tests.sh 01              # By number
./run_tests.sh basic           # By keyword
./run_tests.sh 01 03 05        # Multiple tests

Test Categories

Core Locking

ID Test Description
00 00-setup.js Deploy contracts, configure signers and tokens (always runs first)
01 01-basic-lock.js Create a lock, add tokens, verify balances and lock state
02 02-price-lock.js Create locks with on-chain price conditions (Uniswap oracles)
07 07-lock-history.js Verify lock history tracking and event logs
30 30-get-all-locks.js Retrieve and paginate all locks across many tokens (stress test)
40 40-multilock-surplus.js Multi-lock operations and surplus token handling
44 44-zero-duration-lock.js Zero-duration locks are immediately time-unlockable
90 90-lock-closure-with-history.js Closing a lock is constant-cost regardless of accumulated history; duration bound
91 91-lock-closure-and-duration-bounds.js Regular and vesting closure cost, history retention, and MAX_LOCK_DURATION bounds
72 72-lock-pagination-and-counter.js Lock counter and paginated enumeration
101 101-accounting-sweep-and-pagination.js Token accounting under sweeps, pagination invariants
64 64-permissionless-topup.js addToLock is open by design and can only pull the caller's own funds
63 63-fee-on-transfer-credit.js Fee-on-transfer tokens are credited by what actually arrived
70 70-topup-overflow-gainloss.js Top-up overflow safety and gain/loss pool consistency

Price Conditions & Oracles

ID Test Description
05 05-price-conditions.js UPSIDE / DOWNSIDE price condition logic
09 09-target-price-immutable.js Verify target price cannot be modified after lock creation
31 31-exhaustive-prices.js Exhaustive price calculation scenarios (edge cases)
32 32-reference-pools.js Reference pool configurations for multiple DEX versions
42 42-threshold-v3-inverse.js Uniswap V3 inverse pair math and threshold edge cases
51 51-downside-ethpair-paths.js DOWNSIDE direction combined with ETH-routed pairs
56 56-pricecalculator-edges.js PriceCalculator edge branches
57 57-fullmath-edges.js FullMath edge coverage
62 62-time-backstop-price-lock.js The time backstop still applies to a price-locked lock
67 67-v3-price-underflow.js V3 price underflow is symmetric - no silent zero

Vesting & Unlock

ID Test Description
10 10-eip712-unlock.js EIP-712 typed signature unlock flow
18 18-vesting-unlock-sig.js Progressive vesting with multi-sig unlock
54 54-vesting-negatives.js Rejected vesting configurations
68 68-vesting-duration-guard.js A schedule that could never complete before unlockTime is refused
71 71-vesting-percent-and-history.js Percentage mode resolved against a frozen basis, plus claim history
92 92-vesting-percent-cap-grief.js Dust top-ups cannot inflate the rate or void a signed ceiling
100 100-vesting-price-cross.js Vesting interacting with price conditions
104 104-archive-direction-and-decimals.js Lock archive direction and live decimals() reads

Multi-Signature Governance

ID Test Description
14 14-batch-signers.js Batch add/remove signers
15 15-threshold-update.js Update M-of-N threshold with signatures
16 16-create-lock-sig.js Lock creation requiring multi-sig approval
34 34-threshold-under-5.js Threshold configurations with fewer than 5 signers
73 73-genesis-threshold-invariant.js threshold <= signers holds from construction onward (anti-freeze)
98 98-threshold-one-money-paths.js Every money path under a 1-of-1 configuration

Security & Access Control

ID Test Description
04 04-lock-security.js Unauthorized access, invalid inputs, boundary checks
06 06-lock-rescue.js Multi-sig token rescue with guards against active locks
43 43-rescue-lock-lifecycle.js Rescue interaction with the full lock lifecycle
45 45-rescue-native.js Multi-sig native coin rescue (force-sent funds)
36 36-signature-malleability.js EIP-712 signature malleability protection (ECDSA s value)
38 38-lockmanager-price-coverage.js LockManager price logic edge cases
39 39-signer-access-coverage.js Signer access control exhaustive coverage
35 35-v3-math-overflow.js Uniswap V3 math overflow protection
58 58-entrypoint-lockdown-matrix.js Exhaustive matrix: every entry point against a non-signer
59 59-residual-revert-paths.js Residual revert paths not covered elsewhere
60 60-adversarial-fund-theft.js Direct attempts to walk funds out of a locker
61 61-hardening-regression.js Regressions for previously closed holes
74 74-rogue-signer-rescue-block.js A lone signer cannot force a rescue
75 75-v3-price-quantum-zero.js A V3 pool truncating to a usable zero price
93 93-module-coherence-invariant.js Modules must all point at the same peers (ERR_010/ERR_011)
95 95-ethpair-counterasset.js The counter-asset of an ETH-routed pair must really be WETH
96 96-signer-freeze-via-surplus-sweep.js Freezing funds costs the same quorum as releasing them
97 97-price-gate-cross-defeats.js Four price-gate defeats, closed by the canonical stablecoin registry
99 99-launch-module-substitution.js A canonical shell wired to a hostile module is rejected
103 103-signature-encoding-negatives.js Malformed signature encodings
47 47-operations-surface-removed.js Removed operation surface stays removed; onlyLocker gating
48 48-lockercontract-negatives.js LockerContract negative paths
50 50-lockmanager-negatives.js LockManager negative paths and edge coverage
52 52-validationhandler-negatives.js ValidationHandler negative paths and exact revert reasons
53 53-signermanager-negatives.js SignerManager negative paths and neutral getters
55 55-libops-reverts.js Library-level revert coverage
66 66-signer-bounds-swap.js Progressive onboarding, anti-freeze invariant, 1–20 bounds

Replay Protection

ID Test Description
23 23-threshold-replay-protection.js Replay protection on threshold updates
25 25-batch-signers-replay.js Replay protection on batch signer operations
26 26-unlock-replay.js Replay protection on unlock transactions
27 27-create-lock-replay.js Replay protection on lock creation
46 46-rescue-replay.js Replay protection on token and native rescues
49 49-batch-update-and-replay.js Batch signer update guards + on-chain replay protection

Launch Suite

ID Test Description
76 76-allocation-round.js Merkle allocation round: finalize, claim, vesting
77 77-allocation-scale.js Allocation at scale (large trees)
78 78-presale-round.js Presale tranches, soft cap, settlement, refunds
79 79-presale-raiselock.js Raise-lock creation, execution, and retargeting
85 85-launch-vault-flow.js Air-gapped vault flow for round creation
86 86-launch-global-stats.js Cross-round aggregate statistics
94 94-presale-leg-isolation.js One blacklisted stablecoin must not strand the whole raise
102 102-launch-edge-states.js Round edge states and transitions

Adversarial Test Rounds

Each of these mounts real attacks and passes only when every one is blocked.

ID Test Description
80 80-launch-adversarial.js Round 1 - impostor locker, vesting-drained lock target, proceeds sweep
81 81-launch-adversarial-2.js Round 2 - the price door, cap-table pollution
82 82-launch-adversarial-3.js Round 3 - fee-switch tokens, verifier verdicts, forgeable history
83 83-launch-adversarial-derived.js Round 4 - derived attacks and TOCTOU on the verified horizon
84 84-launch-adversarial-actors.js Round 5 - investor, team, and code-author threat models
93 93-module-coherence-invariant.js Round 6 - split module wiring behind canonical bytecode
99 99-launch-module-substitution.js Round 6 - module substitution behind a canonical codehash

Deploying to EVM Networks

The deployment process is entirely configured via environment variables. You can deploy to any preset EVM chain (with default public RPCs or optional custom RPC overrides) or to any generic EVM chain by specifying its RPC URL and Chain ID.

Step 1: Configure Environment Variables

Create your .env file by copying the template:

cp .env.example .env

Open .env and fill in the values:

# ------------------------------------------------------------
# 1. Deployer Credentials (Provide EITHER Private Key OR Mnemonic)
# ------------------------------------------------------------
# If both are set, PRIVATE_KEY takes precedence.
PRIVATE_KEY=0xYourPrivateKeyHere
# OR:
MNEMONIC=word1 word2 word3 ... word12

# ------------------------------------------------------------
# 2. Locker Parameters
# ------------------------------------------------------------
# INITIAL_SIGNERS: Comma-separated list of authorized multi-sig signers (3 to 20).
INITIAL_SIGNERS=0xSigner1,0xSigner2,0xSigner3

# THRESHOLD: Number of required signer approvals (must be >= 3 and <= number of signers).
THRESHOLD=3

# ------------------------------------------------------------
# 3. Uniswap Price Condition / WETH Configuration
# ------------------------------------------------------------
# WETH_ADDRESS: Required for on-chain price evaluation (PriceCalculator).
# Set to the WETH or wrapped native token address of your target chain (see table below).
WETH_ADDRESS=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

# CUSTOM_WETH_ADDRESSES: Optional comma-separated list of additional
# wrapped-native token addresses, registered immutably at deploy time.
# CUSTOM_WETH_ADDRESSES=0xToken1,0xToken2

# ------------------------------------------------------------
# 4. Target Network Configuration (Only required for --network custom / mainnet)
# ------------------------------------------------------------
RPC_URL=https://your-custom-rpc-url-here
CHAIN_ID=1

# ------------------------------------------------------------
# 5. Optional Preset Network RPC Overrides (e.g. for --network base)
# ------------------------------------------------------------
# BASE_RPC_URL=https://mainnet.base.org
# BSC_RPC_URL=https://binance.llamarpc.com
# POLYGON_RPC_URL=https://polygon.llamarpc.com
# ARBITRUM_RPC_URL=https://arbitrum.llamarpc.com
# OPTIMISM_RPC_URL=https://optimism.llamarpc.com
# SEPOLIA_RPC_URL=https://ethereum-sepolia-rpc.publicnode.com
# AMOY_RPC_URL=https://rpc-amoy.polygon.technology
# BSC_TESTNET_RPC_URL=https://bsc-testnet-rpc.publicnode.com

Step 2: Compile Contracts

Compile the contracts using Hardhat:

npx hardhat compile --force

Step 3: Run Deployment Script

Deploy the contracts to the network of your choice.

Option A: Deploy using a Preset Network Name

You can deploy directly to standard networks configured in hardhat.config.js. If you haven't set custom RPC overrides in .env, the script will automatically use public endpoints:

# Mainnets
npx hardhat run scripts/deploy.js --network base
npx hardhat run scripts/deploy.js --network arbitrum
npx hardhat run scripts/deploy.js --network bsc
npx hardhat run scripts/deploy.js --network polygon
npx hardhat run scripts/deploy.js --network ethereum
npx hardhat run scripts/deploy.js --network optimism

# Testnets
npx hardhat run scripts/deploy.js --network sepolia
npx hardhat run scripts/deploy.js --network amoy
npx hardhat run scripts/deploy.js --network bscTestnet

Option B: Deploy to a Custom EVM Chain

To deploy to any EVM chain not preset above, configure RPC_URL and CHAIN_ID in .env, and run the deployment targeting the custom network:

npx hardhat run scripts/deploy.js --network custom

What the Deployment Script Does

The deployment script executes the following steps:

  1. Validates Configuration β€” Checks for active RPC, balance, WETH address validity, signer count (3-20), and threshold rules.
  2. Deploys Core Modules β€” Deploys PriceCalculator, ValidationHandler, LockManager, SignerManager, and VestingManager.
  3. Deploys Locker Entry Point β€” Deploys LockerContract using the module addresses, initial signers, and threshold.
  4. Saves Deployment Metadata β€” Generates a deployed-addresses-<chainId>.json metadata file containing all deployed addresses and deployment parameters.
  5. Prints Integration Guide β€” Outputs step-by-step instructions to register your new Locker on the protocol.

Register on Locker Protocol

Once your contracts are deployed, register your Locker on the platform:

  1. Go to lockerprotocol.com
  2. Connect your wallet (MetaMask) on the correct network
  3. Click "Add Custom Locker"
  4. Paste your LockerContract address (the one labelled as the entry point in the deployment output)
  5. Give your Locker a name (optional)
  6. Click "Add Locker"

Your Locker is now visible and manageable through the Locker Protocol interface.


Supported Chains

Chain Chain ID WETH Address
Ethereum 1 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
BSC 56 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
Polygon 137 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619
Arbitrum 42161 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1
Optimism 10 0x4200000000000000000000000000000000000006
Base 8453 0x4200000000000000000000000000000000000006
Avalanche 43114 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7
Linea 59144 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f
zkSync Era 324 0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91
Robinhood 4663 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73

Security

Multi-Signature (EIP-712)

All critical operations require M-of-N multi-signature approval:

  • Unlock tokens - requires threshold signatures
  • Rescue tokens or native funds - requires threshold signatures + nonce
  • Update signers - requires threshold signatures + nonce
  • Update threshold - requires threshold signatures + nonce

Replay Protection

Every signed operation includes a per-operation nonce that is incremented after execution, making signature replay impossible.

Air-Gapped Signing

Private keys can be kept on a completely offline device. Signature requests and responses are exchanged via animated QR codes using the BC-UR protocol.

OpenZeppelin Primitives

  • ReentrancyGuard - protection against reentrancy attacks
  • SafeERC20 - safe token transfer handling
  • Checks-Effects-Interactions pattern throughout

Symmetric Authority Over Funds

Releasing funds and immobilising them cost the same authority. Crediting a token's rescuable surplus into a lock is a quorum-gated SweepSurplus operation - the exact complement of rescueToken over the same quantity. It used to be a lone-signer call, which let one signer sweep a token's surplus into a price-free century-long lock and freeze it against the full quorum.

Chain-Aware Canonical Registries

isStablecoin and isWETH are keyed by block.chainid: on any chain, only that chain's own entries can match, and everything else falls through to the immutable per-deployment list configured at construction.

This is not defensive styling. A flat cross-chain address set is only as strong as the key management of every project in it: a CREATE address is keccak(rlp(sender, nonce)) with no chain component, so anyone holding a deployer's key can claim the same address on any chain where that account is still at the matching nonce. That has already happened to a major stablecoin - one well-known DAI address is genuine on two chains and attacker-controlled on a third, where the code sitting there is not even an ERC-20. An address only identifies an asset together with its chain id.

Both registries are immutable after construction, on purpose: a standing power to extend what counts as a dollar is a standing power to mint a fake one. Adopting a new canonical stablecoin therefore requires redeploying PriceCalculator.

Launch Suite Trust Anchors

A PresaleRound that advertises "the raise is locked" verifies that claim on-chain before the round can exist:

  • the team's locker must match the canonical codehash, and so must the two modules that carry the promise (VestingManager, LockManager) - pinning the shell alone is not enough, since its modules are constructor arguments held in ordinary storage;
  • the lock's release time is read through earliestReleaseTime, which accounts for every door (time, price, and vesting), not just unlockTime;
  • both checks run again at executeRaiseLock and on every retarget, so substituting a module after creation is caught too.

Responsible Disclosure

If you find a vulnerability, please see SECURITY.md for reporting instructions.


Project Structure

locker-smart-contracts/
β”œβ”€β”€ contracts/                  # Solidity smart contracts
β”‚   β”œβ”€β”€ LockerContract.sol      # Entry point
β”‚   β”œβ”€β”€ LockManager.sol         # Lock storage & conditions
β”‚   β”œβ”€β”€ SignerManager.sol       # Signer management
β”‚   β”œβ”€β”€ ValidationHandler.sol   # EIP-712 multi-sig engine
β”‚   β”œβ”€β”€ VestingManager.sol      # Progressive vesting
β”‚   β”œβ”€β”€ PriceCalculator.sol     # Uniswap V2/V3 oracle + canonical asset registries
β”‚   β”œβ”€β”€ FullMath.sol            # Math library
β”‚   β”œβ”€β”€ LaunchFactory.sol       # Launch Suite - per-chain canonical rails
β”‚   β”œβ”€β”€ PresaleRound.sol        # Launch Suite - stablecoin-only sale
β”‚   β”œβ”€β”€ AllocationRound.sol     # Launch Suite - merkle allocation
β”‚   └── mocks/                  # Test-only contracts
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ deploy-local.js         # Local testnet deployment
β”‚   β”œβ”€β”€ deploy.js               # Mainnet deployment
β”‚   └── verify-round.mjs        # Off-chain verifier for a finalized round
β”œβ”€β”€ test/
β”‚   β”œβ”€β”€ tests/                  # 91 test files
β”‚   β”œβ”€β”€ core/utils.js           # Test utilities
β”‚   └── run_tests.sh            # Test runner
β”œβ”€β”€ hardhat.config.js           # Hardhat configuration
β”œβ”€β”€ package.json                # Dependencies
β”œβ”€β”€ .env.example                # Environment template
β”œβ”€β”€ LICENSE                     # Proprietary License
└── SECURITY.md                 # Security policy

Compiler Settings

Solidity: 0.8.20
Optimizer: enabled (runs: 1)
viaIR: true

License

This project is licensed under a proprietary non-commercial license. You are permitted to use, copy, modify, and run the software for non-commercial purposes only. Commercial use, reproduction, redistribution, or commercialization is strictly prohibited. See the LICENSE file for details.


Website: lockerprotocol.com Β· Security: SECURITY.md

About

πŸ” Solidity smart contracts for Locker Protocol β€” ERC-20 token locking with multi-signature (M-of-N) governance, EIP-712 air-gapped signing, on-chain price oracles (Uniswap V2/V3), vesting schedules, and 1-click deployment registry. Deployed on Ethereum, ready for 9 EVM chains.

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages