Subscryption

Decentralized subscription service powered by PYUSD smart contracts.

Subscryption

Created At

ETHOnline 2025

Project Description

This project, PYUSD Subscription Service, is a decentralized application (dApp) designed to manage programmable, recurring subscription payments using PayPal USD (PYUSD) stablecoin on blockchain networks. It aims to provide a modern alternative to traditional subscription models by leveraging blockchain technology.

Core Concept The system allows creators or service providers to define subscription plans with specific prices (in PYUSD) and billing periods (e.g., monthly). Users can then subscribe to these plans using their crypto wallets (like MetaMask) by paying with PYUSD. The smart contract handles the logic for managing subscriptions, tracking payment cycles, and processing renewals.

Key Benefits Programmable Payments: Automates recurring billing using smart contract logic. Cost-Effective: Aims for low transaction fees, particularly when deployed on Layer 2 networks like Arbitrum. Always Available: Operates 24/7 without traditional banking hour limitations. Global Reach: Accessible to anyone with an internet connection and a crypto wallet. Transparency: All subscription activities and payments are recorded on the public blockchain ledger.

How it's Made

Core Technologies 🛠️ The project combines smart contracts on the backend with a web interface on the frontend.

Smart Contracts: Written in Solidity (version 0.8.24 specifically). These contracts handle all the core logic for subscriptions, payments, and plan management on the blockchain.

Development Environment: Hardhat is used as the primary toolchain. It manages compiling the Solidity code, running tests, deploying contracts to networks (like local Hardhat network, Ethereum Sepolia, Arbitrum Sepolia), and verifying contracts on block explorers (Etherscan/Arbiscan).

Blockchain Interaction: Ethers.js is the library used both in the Hardhat scripts (deployment, testing, plan updates) and the frontend to interact with the Ethereum blockchain (reading data, sending transactions, connecting wallets). The simple HTML frontend uses Ethers v5 via CDN, while the Next.js setup uses Ethers v6.

Payment Token: PayPal USD (PYUSD) is the designated ERC20 token for all subscription payments. The contract specifically interacts with the PYUSD token contract address provided during deployment.

Backend: Smart Contracts 🧱 Core Logic (PYUSDSubscription.sol): This contract defines the structures for SubscriptionPlan (name, price, period, etc.) and UserSubscription (tracking user status). It implements functions for creating/managing plans (createPlan, updatePlanStatus), handling subscriptions (subscribe, subscribeWithPermit, cancelSubscription), processing recurring payments (processPayment), and checking status (isSubscribed, getUserSubscription).

Security & Standards: It inherits from OpenZeppelin Contracts for standard, audited implementations of:

Ownable: Restricts administrative functions (like creating plans) to the contract deployer.

ReentrancyGuard: Protects against reentrancy attacks on functions like subscribe and processPayment.

Pausable: Allows the owner to pause critical functions (subscribe, subscribeWithPermit) in emergencies.

PYUSD Interaction (IPYUSD.sol): This interface defines the necessary ERC20 functions (balanceOf, approve, transferFrom, allowance) and the EIP-2612 permit function, allowing the main contract to interact with any PYUSD token contract adhering to this interface. The use of permit enables gasless approvals for users.

Decimal Handling: The deployment and plan update scripts explicitly use ethers.parseUnits("amount", 6) to handle PYUSD's 6 decimal places correctly when setting plan prices in the contract.

Frontend: User Interface 🖥️ Simple HTML/JS Interface (frontend/index.html): A basic frontend is provided using vanilla JavaScript and Ethers.js (v5 loaded from CDN).

Wallet Connection: Connects to the user's browser wallet (like MetaMask) using window.ethereum.request({ method: 'eth_requestAccounts' }) and ethers.providers.Web3Provider. It also includes logic to prompt the user to switch to the correct network (Sepolia).

Contract Interaction: Initializes ethers.Contract instances for both the subscription contract and the PYUSD token contract using their addresses and ABIs (hardcoded or potentially loaded from JSON files like PYUSDSubscription.json and IPYUSD.json).

Functionality: Displays plans (initially hardcoded prices, but loads actual prices from the contract via loadPlanPrices), allows users to call approve on the PYUSD contract, and then subscribe on the main contract. Basic status messages are shown.

Decimal Handling: Uses ethers.utils.formatUnits(value, 6) and ethers.utils.parseUnits("amount", 6) correctly for displaying and handling PYUSD amounts.

Next.js Structure (Experimental/Alternative): The frontend directory also contains files (page.js, layout.js, package.json) suggesting a Next.js/React setup using Ethers.js v6. However, the primary runnable frontend seems to be the index.html served by simple-server.js.

Development & Deployment Workflow ⚙️ Hardhat Tasks: Standard Hardhat tasks (compile, test, run scripts/deploy.js) are used for the smart contract lifecycle.

Configuration: Network RPC URLs, private keys, and API keys for verification are managed via environment variables (.env file, template provided) and loaded in hardhat.config.js. The crucial PYUSD contract address is also passed via environment variables.

Testing: Basic tests are set up using Hardhat's testing environment, which integrates Ethers.js and Chai matchers.

Notable Points / "Hacky" Details 🤔 Dual Frontend: Having both a simple index.html and a Next.js setup within the frontend directory is slightly unusual. It might indicate an ongoing migration or experimentation phase. The simple-server.js specifically serves index.html, suggesting the Next.js part isn't the primary focus currently.

Hardcoded Addresses/ABIs: The index.html file hardcodes the contract address, PYUSD address, and ABIs directly within the script tag. While simple for demonstration, this isn't ideal for maintainability or deployment flexibility compared to using environment variables or configuration files (as seen in the Next.js setup).

Decimal Handling Correction: Previous versions of the code incorrectly used ethers.parseEther (18 decimals) for PYUSD (6 decimals) in the deployment/update scripts. This has been corrected to use ethers.parseUnits("amount", 6), which was a critical bug fix. The frontend index.html also now correctly uses formatUnits(value, 6).

Overall, the project uses a standard Hardhat + Ethers.js + Solidity stack for the backend, with OpenZeppelin for security patterns. The frontend leverages Ethers.js for wallet and contract interactions, currently presented through a simple HTML/JS page. The choice of PYUSD integrates PayPal's stablecoin into a decentralized subscription model.

background image mobile

Join the mailing list

Get the latest news and updates