A decentralized subscription management system built on Ethereum. This smart contract enables anyone to create and manage subscription-based services with customizable pricing, duration, and access control.
Solidity: 0.8.31
Framework: Foundry
Test Coverage: 94% statements, 100% lines, 80% branches
License: MIT
The platform allows service providers to create subscription plans with custom parameters, while users can subscribe, extend, or gift subscriptions. Each plan has its own owner, pricing, and duration settings.
For Service Providers:
- Create subscription plans with custom price and duration
- Pause or resume services at any time
- Update subscription pricing
- Withdraw accumulated earnings securely
For Users:
- Subscribe to any active service
- Automatically extend existing subscriptions
- Gift subscriptions to other addresses
- Check subscription status and expiration dates
The contract uses a single-file architecture (167 lines) with optimized storage layout and security patterns:
struct Plan {
address owner; // Plan creator
uint64 duration; // Subscription period in seconds
bool isActive; // Can be paused by owner
uint256 price; // Subscription cost in Wei
}| Function | Access | Description |
|---|---|---|
createPlan(price, duration) |
Public | Create a new subscription service |
subscribe(planId) |
Public | Pay for or extend a subscription |
giftSubscription(planId, recipient) |
Public | Purchase subscription for another address |
isSubscriptionActive(user, planId) |
View | Check if subscription is active |
userSubscriptions(user, planId) |
View | Get subscription expiration timestamp |
updatePlanPrice(planId, newPrice) |
Owner Only | Change subscription price |
togglePlanStatus(planId) |
Owner Only | Pause/resume service |
withdraw() |
Owner Only | Withdraw accumulated earnings |
curl -L https://foundry.paradigm.xyz | bash
foundryupgit clone https://github.com/KOMPAI-DEV/SubscriptionPlatform.git
cd SubscriptionPlatform
forge install
forge buildforge test # Run all tests
forge test -vvv # Verbose output
forge test --gas-report # Gas usage report
forge coverage # Coverage reportThe project includes 20 comprehensive tests covering core functionality, security, and edge cases:
- Core Operations: Plan creation, subscriptions, withdrawals, status checks, gifting
- Security: Reentrancy protection, overflow prevention, access control
- Error Cases: Input validation, state checks, payment verification
- Fuzz Testing: 2 fuzz tests with 256 randomized runs each for payment validation
- Edge Cases: Subscription extensions, gift subscriptions, plan status toggling
Current test coverage: 94% statements, 100% lines, 80% branches
The contract implements multiple security layers:
- Reentrancy Protection: Uses OpenZeppelin's ReentrancyGuard on withdrawal function
- CEI Pattern: State updates occur before external calls
- Pull Payment: Earnings accumulate in contract; owners withdraw when ready
- Overflow Protection: Explicit checks for timestamp arithmetic
- Input Validation: Custom errors for gas-efficient reverts
- Access Control: Custom modifiers restrict owner-only functions
Variables packed into minimal storage slots (2 instead of 4) saves ~20,000 gas per plan creation.
Using error selectors instead of string messages reduces revert costs by ~50 gas.
Safe operations bypass overflow checks, saving ~25 gas per increment/addition.
Eliminates unnecessary struct wrapper for subscriptions, saving ~80 gas per access.
Deployment: 660,761 gas (local) / 640,013 gas (Sepolia)
Contract Size: 2,831 bytes
createPlan: ~90,621 gas (avg)
subscribe: ~26,947 gas (avg)
giftSubscription: ~26,708 gas (avg)
withdraw: ~31,839 gas (avg)
updatePlanPrice: ~27,232 gas (avg)
togglePlanStatus: ~26,073 gas (avg)
Note: Deployment gas varies slightly between local testing and live networks due to compiler nuances and network transaction overhead. Without optimization, deployment would cost ~1,119,688 gas - the optimizer reduces this by ~43%.
// Deploy the contract
SubscriptionPlatform platform = new SubscriptionPlatform();
// Create a monthly subscription plan
// Price: 0.01 ETH (approx $30), Duration: 30 days
platform.createPlan(0.01 ether, 30 days);
// Subscribe to plan #0 by sending the correct ETH amount
platform.subscribe{value: 0.01 ether}(0);
// Check if subscription is active for a user
bool active = platform.isSubscriptionActive(userAddress, 0);
// Withdraw accumulated earnings (plan owner only)
platform.withdraw();Sepolia Testnet:
- Contract:
0xd3155ba0cf4f9748294f602c0038c4b0d5f12039 - Verified on Etherscan
- OpenZeppelin Contracts v5.5.0 (ReentrancyGuard only)
- Forge Standard Library v1.9.6 (testing)
Khosro Sharifi - January 2026
MIT License - see LICENSE file for details