A secure, fully functional Multi-Signature (Multisig) smart contract built on Solana using the Anchor framework. This program allows a group of designated owners to jointly manage funds and execute transactions based on a configurable threshold of approvals.
- Features
- Architecture
- Prerequisites
- Getting Started
- Testing
- Program Instructions
- Error Codes
- Security Considerations
- License
- Dynamic Ownership: Support for up to 10 distinct owners per multisig instance.
-
Customizable Thresholds: Require any number of approvals (
$M$ of$N$ ) to execute a transaction. - Secure Execution: Transactions are executed directly from the Multisig PDA, ensuring funds are strictly managed by the program.
- Deterministic PDAs: Both the Multisig and its Transactions are derived using deterministic seeds for easy discovery.
- Comprehensive Edge-Case Handling: Protects against duplicate signers, overflow attacks, and unauthorized execution.
-
MultisigAccount- Tracks the list of
owners(up to 10). - Stores the required
thresholdof signatures. - Maintains a
transaction_index(nonce) to ensure unique PDAs for every proposed transaction.
- Tracks the list of
-
TransactionAccount- Stores the destination address (
to). - Stores the amount of lamports to transfer (
amount). - Tracks approvals via a boolean vector (
signers). - Maintains execution state (
executed) to prevent double-spending.
- Stores the destination address (
Ensure you have the following installed before getting started:
- Rust (latest stable)
- Solana CLI (v1.16+ recommended)
- Anchor CLI (v0.29+)
- Node.js & Yarn (or npm/bun)
-
Clone the repository
git clone https://github.com/Enmilo-dev/sol-multisig cd sol-multisig -
Install dependencies
npm install # or bun install / yarn install -
Build the Anchor program
anchor build
-
Sync program ID Update the program ID in
Anchor.tomlandprograms/multisig/src/lib.rswith the newly generated key fromtarget/deploy/multisig-keypair.json.anchor keys sync
The repository includes a comprehensive Mocha/Chai test suite validating both the happy paths and security edge cases (e.g., threshold limits, duplicate authorizations).
To run the local test validator and the full suite:
anchor testInitializes a new MultisigAccount PDA.
- Parameters:
owners(Array of Pubkeys),threshold(u8). - Validation: Ensures 2 <= threshold <= owners.len() <= 10. Checks for duplicate owners.
Proposes a new transfer of SOL from the multisig.
- Parameters:
amount(u64 in lamports),recipient(Pubkey). - Behavior: Derives a new PDA for the transaction, sets the creator as the first signer automatically, and increments the multisig's transaction index.
Appends a signature to a pending transaction.
- Behavior: Flips the signer's index in the
TransactionAccount.signersarray totrue. - Validation: Ensures the transaction hasn't been executed and the signer hasn't already approved.
Executes the transaction and transfers funds to the recipient.
- Behavior: Validates that the number of approvals meets the required
threshold. If valid, transfers lamports from the Multisig PDA to the recipient PDA and marks the transaction as executed.
| Code | Name | Description |
|---|---|---|
6000 |
OwnersCountExceeded |
Maximum of 10 owners allowed |
6001 |
OwnersCountNotMet |
Minimum of 2 owners required |
6002 |
DuplicateOwner |
The owners array contains duplicates |
6003 |
InvalidOwner |
The signer is not an authorized owner |
6004 |
ThresholdExceeded |
Threshold cannot exceed the number of owners |
6005 |
ThresholdNotMet |
Not enough approvals to execute transaction |
6006 |
InvalidAmount |
Transaction amount must be greater than 0 |
6007 |
TransactionAlreadyExecuted |
This transaction has already been processed |
6008 |
AlreadyApproved |
This owner has already approved this transaction |
6009 |
Overflow |
Math overflow error |
- Rent Exemption: Standard Solana rent logic applies. When verifying execution balances in tests, remember to account for the base rent-exemption lamports held by initialized PDAs.
- Double Spend Protection: Transactions use a boolean
executedflag which strictly prevents replay attacks. - Signer Verification: All instructions verify that the executing account signed the transaction via Anchor's
Signer<'info>wrapper.
This project is licensed under the MIT License - see the LICENSE file for details.