Testing & Analysis
The Colored Keys contracts undergo comprehensive testing through unit tests, integration tests, gas profiling, and multiple security analysis tools. This document details the testing approach, coverage metrics, and validation results.
Test Commands
Execute tests using pnpm with Hardhat:
pnpm test # Complete test suite
pnpm test:gas # Tests with gas consumption reporting
pnpm test:coverage # Code coverage analysis
pnpm coverage:gas # Combined coverage and gas reporting
pnpm test:key # Base KeyToken tests
pnpm test:one # OnePerWalletKeyToken tests
pnpm test:color # ColorGenerator library tests
pnpm test:libs # All library integration tests
Test Architecture
The test suite validates both standard ERC-721 compliance and custom functionality through 87 test cases executing in approximately 11 seconds.
Contract-Specific Testing
OnePerWalletKeyToken (21 tests) The production contract tests focus on the one-token-per-wallet restriction:
- Minting restriction: Validates that second mint attempts fail with appropriate error
- Transfer restriction: Ensures transfers fail when recipient already owns a token
- Self-transfer allowance: Confirms transfers to same address are permitted
- Burn and re-mint: Verifies addresses can mint after burning their token
- Batch mint override: Confirms mintBatch enforces quantity=1
KeyToken (41 tests) Base contract tests cover standard NFT operations and on-chain generation:
- Token minting with sequential IDs starting from 1
- Color generation and storage
- SVG generation and Base64 encoding
- Metadata construction and URI generation
- Token enumeration and ownership queries
Libraries (12 tests) Library tests validate color and SVG generation:
- Deterministic color generation from seeds
- Hex string conversion
- Color equality detection (exact match only)
- Color inversion for contrast
- SVG element construction
ColorGeneratorDetailed (13 tests)
Edge‐case tests for hex‐to‐uint8 boundaries, uppercase‐hex panic, overflow panic, and color‐inversion logic.
GasProfiling (9 tests)
Profiles gas for mint, batch mint, transfer (incl. safe), approvals, burns, composite scenarios and summary statistics.
Coverage Analysis
Overall Coverage Metrics
Contract | Statements | Branches | Functions | Lines |
---|---|---|---|---|
OnePerWalletKeyToken.sol | 100% | 100% | 100% | 100% |
KeyToken.sol | 95.83% | 100% | 88.89% | 96.15% |
SVGGenerator.sol | 100% | 100% | 100% | 100% |
ColorGenerator.sol | 57.89% | 16.67% | 66.67% | 62.5% |
Overall System | 88.31% | 69.23% | 89.66% | 87% |
Coverage Analysis
The production contract (OnePerWalletKeyToken) achieves 100% coverage, ensuring complete validation of the ownership restriction mechanism. Lower coverage in ColorGenerator reflects private utility functions that are tested indirectly through public interfaces.
Test Helpers
ColorGeneratorTestHelper
This test contract exposes private library functions for direct testing:
contract ColorGeneratorTestHelper {
function testAreSimilarColors(string memory color1, string memory color2)
public pure returns (bool) {
// Exposes private areSimilarColors function
}
function testInvertColor(string memory color)
public pure returns (string memory) {
// Exposes private invertColor function
}
}
The helper enables testing of color equality detection, which only checks for exact matches rather than visual similarity. This is a known limitation of the current implementation.
EchidnaOnePerWalletKeyToken
The Echidna harness implements invariants for property-based testing:
contract EchidnaOnePerWalletKeyToken is OnePerWalletKeyToken {
function echidna_one_token_per_wallet() public view returns (bool) {
// Validates no address holds more than one token
}
function echidna_token_ownership() public view returns (bool) {
// Ensures ownership consistency
}
}
Security Analysis
The contracts undergo analysis with three security tools:
Security analysis results are documented in their respective pages.
Gas Profiling
Gas consumption measured on Hardhat network with optimizer enabled (200 runs):
Operation | Gas Used | Notes |
---|---|---|
Contract Deployment | 4,127,918 | OnePerWalletKeyToken |
Mint (first) | ~247,500 | Cold storage initialization |
Mint (subsequent) | ~247,500 | Consistent per token |
MintBatch(1) | ~245,300 | Slightly lower than direct mint |
TransferFrom | ~78,000-83,000 | Includes balance check overhead |
SafeTransferFrom | ~83,000 | To EOA address |
Burn | ~47,300 | Token destruction |
Approve (first) | ~49,100 | Cold storage |
Approve (update) | ~27,000 | Changing existing approval |
SetApprovalForAll | ~46,000 | Operator approval |
The one-token-per-wallet restriction adds approximately 5,000 gas to transfer operations due to the additional balance check. Comprehensive gas profiling tests are available in test/GasProfiling.test.ts
.
Critical Test Scenarios
Ownership Restriction Tests
The test suite validates the one-token-per-wallet restriction through multiple scenarios:
Direct Minting Prevention: Attempting to mint a second token fails with AlreadyOwnsToken
error.
Transfer Prevention: Transfers to addresses that already own a token fail with WouldExceedMaxTokensPerWallet
error.
Self-Transfer Allowance: Transfers where from equals to are permitted since they don’t change token count.
Burn and Re-mint Flow: After burning a token, the same address can mint a new one, confirming the restriction is based on current state.
Edge Cases
The tests cover several non-obvious scenarios:
- Approved transfers respect the one-token restriction
- Batch minting is properly restricted to quantity=1
- Empty owner queries return appropriate empty arrays
- Color generation produces valid hex strings for all inputs
Test Execution
Running Tests
Standard test execution:
# Run all tests
pnpm test
# Run specific test file
pnpm test test/OnePerWalletKeyToken.test.ts
# Run with gas reporting
pnpm test:gas
Coverage Generation
Generate and view coverage reports:
# Generate coverage
pnpm test:coverage
# View HTML report
open coverage/index.html
Continuous Integration
Tests run automatically on GitHub Actions for pull requests and direct pushes to the main branch. The CI pipeline validates that all tests pass successfully.
Summary
The Colored Keys contracts demonstrate comprehensive test coverage with particular focus on the production contract’s one-token-per-wallet restriction. The combination of unit tests, property-based testing, and security analysis provides strong assurance of contract reliability. While some library functions show lower coverage metrics, all critical functionality is thoroughly validated through both direct and indirect testing approaches.