Your Daily Web3 Ritual - Upgradeable NFT Edition
Features โข Architecture โข Quick Start โข Documentation โข Security
- Executive Summary
- What is OnChainGM?
- Version 2.0 Highlights
- Architecture
- Features
- Technical Specifications
- Fee Structure
- API Reference
- Deployment Guide
- Conclusion
OnChainGM V2.0 is an innovative Ethereum smart contract that combines the ritualistic daily "Good Morning" (GM) transaction with NFT minting capabilities. Built on a robust upgradeable architecture using the UUPS proxy pattern, this contract enables users to mint unique, date-stamped NFTs every day while supporting a referral reward system.
- โ Daily Engagement: One GM transaction per day creates a sustainable Web3 habit
- โ NFT Collection: Every GM mints a unique, non-transferable GMCard NFT
- โ On-Chain Art: Dynamic SVG generation creates beautiful NFT images with date stamps
- โ Referral Rewards: 15% discount for users, 10% reward for referrers
- โ Upgradeable: Future-proof architecture allows contract improvements
- โ Gas Efficient: Optimized storage and operations minimize transaction costs
- โ Fully On-Chain: No external dependencies, complete decentralization
OnChainGM transforms the Web3 community tradition of "GM" (Good Morning) greetings into a verifiable, collectible on-chain experience. Each day, users can send a single GM transaction that:
- Mints a unique NFT: A beautiful GMCard with the current date
- Records on-chain: Permanent blockchain proof of your daily ritual
- Rewards referrals: Earn discounts and rewards through the referral system
- Builds community: Connect with others through daily engagement
In Web3 communities, "GM" has become a universal greeting that signifies belonging to the crypto/blockchain ecosystem. OnChainGM makes this tradition permanent, verifiable, and collectible.
| Feature | V1.0 | V2.0 |
|---|---|---|
| NFT Minting | โ None | โ ERC-721 GMCards |
| On-Chain Art | โ None | โ Dynamic SVG Generation |
| Upgradeability | โ Immutable | โ UUPS Proxy |
| Referral Discount | โ None | โ 15% User Discount |
| Date Stamps | โ None | โ MM.DD.YYYY Format |
| Owner Controls | โ None | โ Fee Management |
| Transferability | N/A | โ Non-Transferable (Soulbound) |
- ๐จ Dynamic SVG NFTs: Each NFT features a beautiful, on-chain generated image with "GMcards" branding and mint date
- ๐ UUPS Upgradeable: Contract can be upgraded by owner to add features or fix issues
- ๐ Soulbound Tokens: NFTs are non-transferable, making them true proof of daily commitment
- ๐ Enhanced Analytics: Token timestamps enable rich on-chain analytics
- ๐ Referral System: Earn 15% discount as a user, 10% reward as a referrer
- โ๏ธ Configurable Fees: Owner can adjust fees and referral percentages
graph TB
subgraph "User Layer"
U1[User Wallet]
U2[dApp Interface]
U3[Ethers.js/Web3]
end
subgraph "Proxy Layer (UUPS)"
P[ERC1967 Proxy]
end
subgraph "Implementation Contract"
IC[OnChainGMV2]
IC --> ERC721[ERC721Upgradeable]
IC --> OWN[OwnableUpgradeable]
IC --> UUPS[UUPSUpgradeable]
IC --> RE[ReentrancyGuardUpgradeable]
end
subgraph "Storage"
S1[Token Registry]
S2[User Data]
S3[Fee Configuration]
S4[Referral Mapping]
end
subgraph "External"
E1[Fee Recipient]
E2[Referrers]
E3[Blockchain]
end
U1 --> U2
U2 --> U3
U3 --> P
P --> IC
IC --> S1
IC --> S2
IC --> S3
IC --> S4
IC --> E1
IC --> E2
IC --> E3
classDiagram
class OnChainGMV2 {
+onChainGM(address referrer)
+timeUntilNextGM(address user) uint256
+tokenURI(uint256 tokenId) string
+totalSupply() uint256
+getTokenTimestamp(uint256 tokenId) uint256
-_mintGM(address user) uint256
-_handleReferralPayment(address referrer, uint256 amount) uint256
-_generateSVG(string date) string
-_parseTimestamp(uint256 timestamp) tuple
}
class ERC721Upgradeable {
+ownerOf(uint256 tokenId) address
+balanceOf(address owner) uint256
+_mint(address to, uint256 tokenId)
}
class OwnableUpgradeable {
+owner() address
+onlyOwner modifier
}
class UUPSUpgradeable {
+upgradeTo(address newImplementation)
+_authorizeUpgrade(address newImplementation)
}
OnChainGMV2 --|> ERC721Upgradeable
OnChainGMV2 --|> OwnableUpgradeable
OnChainGMV2 --|> UUPSUpgradeable
sequenceDiagram
participant U as User
participant P as Proxy
participant C as Contract
participant R as Referrer
participant F as Fee Recipient
U->>P: onChainGM(referrer) + ETH
P->>C: Forward call
alt First GM Today
C->>C: Check lastGMDay
C->>C: Validate fee amount
C->>C: Mint NFT with timestamp
C->>C: Update lastGMDay mapping
alt Referrer Provided
C->>R: Send referral reward (10%)
alt Payment Fails
C->>C: Emit ReferralFailed event
end
C->>F: Send remaining (90%)
else No Referrer
C->>F: Send full fee
end
C->>U: Emit OnChainGMEvent
C->>P: Return success
P->>U: Transaction confirmed
else Already GMed Today
C->>U: Revert AlreadySentGMToday
end
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Storage Slot Mapping โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Slot 0: _tokenIdCounter (uint256) โ
โ Slot 1: feeRecipient (address) โ
โ Slot 2: GM_FEE (uint256) โ
โ Slot 3: GM_FEE_WITH_REFERRAL (uint256)โ
โ Slot 4: REFERRAL_PERCENT (uint256) โ
โ Slot 5+: lastGMDay mapping โ
โ Slot 6+: tokenTimestamp mapping โ
โ Slot 7+: ERC721 storage (name, symbol)โ
โ Slot 8+: Ownable storage (_owner) โ
โ Slot 50+: Storage gap (__gap[50]) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Storage Gap: The __gap[50] array reserves storage slots for future upgrades, preventing storage collision issues.
- One GM per day: Enforced via UTC day calculation (
block.timestamp / 86400) - Automatic reset: Users can GM again after UTC midnight (00:00:00)
- On-chain verification: No need for external services or oracles
- Standard Fee: 0.000029 ETH (29,000 Gwei)
- Referral Fee: 0.00002465 ETH (15% discount)
- Configurable: Owner can adjust fees via
setGMFee()andsetGMFeeWithReferral()
- Uses OpenZeppelin's
ReentrancyGuardUpgradeable - Protects against reentrancy attacks on
onChainGM()function - Critical for secure ETH transfers
- Token Name: GMCards
- Token Symbol: GM
- Standard: ERC-721 (NFT)
- Transferability: Non-transferable (Soulbound)
- Metadata: Fully on-chain (Base64 encoded JSON)
{
"name": "GMCards #1234",
"description": "OnChainGM Daily Card",
"image": "data:image/svg+xml;base64,...",
"attributes": [
{
"trait_type": "Date",
"value": "12.25.2024"
}
]
}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PROOF OF GM โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โฑโฒ โ
โ โฑ โฒ โ
โ โฑ GM โฒ โ
โ โฒ โฑ โ
โ โฒโฑ โ
โ โ
โ OnChainGM โ
โ Your Daily Web3 Ritual โ
โ โ
โ CERTIFICATE MINTED โ
โ #GMcards MM.DD.YYYY โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
SVG Specifications:
- Dimensions: 500x500 pixels
- Theme: Dark with white text
- Hexagon design around "GM" text
- Date format: MM.DD.YYYY
- Fully generated on-chain
The contract implements a sophisticated on-chain date calculation system:
- Timestamp Parsing: Converts Unix timestamp to year, month, day
- Leap Year Handling: Correctly calculates leap years
- Month Lengths: Accounts for variable month lengths (28-31 days)
- Format: Zero-padded MM.DD.YYYY format
Algorithm Complexity: O(1) for dates after year 2000, O(n) for dates before 2000 (where n = years since epoch)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Referral Flow โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ User A (New User) โ
โ โ โ
โ โโโ> onChainGM(User B's address) โ
โ โ โ
โ โโโ> Pays: 0.00002465 ETH (15% off) โ
โ โ โ
โ โโโ> NFT Minted to User A โ
โ โ
โ User B (Referrer) โ
โ โ โ
โ โโโ> Receives: 0.000002465 ETH (10%) โ
โ โ
โ Fee Recipient โ
โ โ โ
โ โโโ> Receives: 0.000022185 ETH (90%) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Without Referral:
User Pays: 0.000029 ETH (100%)
Fee Recipient: 0.000029 ETH (100%)
With Referral:
User Pays: 0.00002465 ETH (85% of standard)
Referrer Gets: 0.000002465 ETH (10% of paid amount)
Fee Recipient: 0.000022185 ETH (90% of paid amount)
Verification:
User pays: 0.00002465 ETH
Referrer: 0.000002465 ETH (10%)
Fee Recipient: 0.000022185 ETH (90%)
Total: 0.00002515 ETH โ (This doesn't match!)
Correct Calculation:
Standard fee: 0.000029 ETH
User discount: 15% โ User pays 85%
User pays: 0.00002465 ETH
Referrer gets: 0.00002465 ร 10% = 0.000002465 ETH
Fee Recipient: 0.00002465 ร 90% = 0.000022185 ETH
- โ Referrer must be non-zero address
- โ
Cannot refer yourself (
msg.sender != referrer) - โ Cannot use fee recipient as referrer
- โ Referral payment failures don't revert the transaction
- โ
Failed referrals emit
ReferralFailedevent
graph LR
A[User] -->|Call| B[Proxy Contract]
B -->|Delegate Call| C[Implementation V1]
D[Owner] -->|Upgrade| B
B -->|Delegate Call| E[Implementation V2]
F[Storage] -.->|Persists| B
style C fill:#ffcccc
style E fill:#ccffcc
style B fill:#ccccff
style F fill:#ffffcc
Benefits:
- โ State preservation across upgrades
- โ Single contract address (users don't need to migrate)
- โ Gas efficient (no state copying)
- โ Owner-controlled upgrades
Upgrade Process:
- Owner deploys new implementation contract
- Owner calls
upgradeTo(newImplementation)on proxy - Proxy updates implementation address
- All existing state remains intact
- New functionality immediately available
Security:
- Only owner can authorize upgrades
- Storage layout must be compatible
- Storage gap prevents collisions
- Can add new state variables at end of storage
| Property | Value |
|---|---|
| Solidity Version | ^0.8.0 |
| License | MIT |
| Proxy Pattern | UUPS (ERC1967) |
| NFT Standard | ERC-721 |
| Initialization | initialize() function |
| Storage Gap | 50 slots reserved |
The contract implements the ERC-721 standard with modifications:
- โ
balanceOf(address owner) โ uint256 - โ
ownerOf(uint256 tokenId) โ address - โ
tokenURI(uint256 tokenId) โ string - โ
totalSupply() โ uint256(extension)
- โ
transferFrom()- Reverts with custom error - โ
safeTransferFrom()- Reverts with custom error - โ
approve()- Reverts with custom error - โ
setApprovalForAll()- Reverts with custom error
Rationale: GMCards are "Soulbound" NFTs - they represent daily commitment and should not be transferable. This makes each NFT a true proof of daily ritual.
Proxy Contract (ERC1967Proxy)
โโโ Storage: All state variables
โโโ Logic: Delegates to implementation
โโโ Upgrade: Calls upgradeTo() on implementation
Implementation Contract (OnChainGMV2)
โโโ Logic: All function implementations
โโโ Storage: Defines storage layout
โโโ Upgrade: _authorizeUpgrade() checks ownership
When upgrading:
- โ
All mappings preserved (
lastGMDay,tokenTimestamp) - โ
All state variables preserved (
_tokenIdCounter, fees, etc.) - โ All NFT ownership preserved
- โ All token metadata preserved
function _authorizeUpgrade(address newImplementation)
internal
onlyOwner
override
{}Only the contract owner can authorize upgrades, preventing unauthorized modifications.
| Scenario | User Pays | Referrer Gets | Fee Recipient Gets | Notes |
|---|---|---|---|---|
| No Referral | 0.000029 ETH | - | 0.000029 ETH | Standard fee |
| With Referral | 0.00002465 ETH | 0.000002465 ETH (10%) | 0.000022185 ETH (90%) | 15% user discount |
if (referrer == address(0)) {
// No referral
requiredFee = GM_FEE; // 0.000029 ETH
feeRecipient receives = msg.value; // 100%
} else {
// With referral
requiredFee = GM_FEE_WITH_REFERRAL; // 0.00002465 ETH (85% of standard)
referrer receives = msg.value * REFERRAL_PERCENT / 100; // 10% of paid amount
feeRecipient receives = msg.value - referralAmount; // 90% of paid amount
}Default Address: 0x7500A83DF2aF99B2755c47B6B321a8217d876a85
The fee recipient can be changed by the contract owner using setFeeRecipient(address newRecipient).
- Daily Cost: 0.000029 ETH (~$0.06 at $2,000/ETH)
- With Referral: 0.00002465 ETH (~$0.05 at $2,000/ETH)
- Benefit: Unique NFT collection, community participation
- Reward per Referral: 10% of paid amount (0.000002465 ETH)
- Potential Earnings: Unlimited referrals
- Benefit: Passive income from community growth
- Revenue per GM: 0.000029 ETH (standard) or 0.000022185 ETH (referral)
- Sustainability: Supports contract maintenance and development
Sends a daily GM transaction and mints an NFT.
Parameters:
referrer(address): Optional referrer address. Useaddress(0)for no referral.
Requirements:
- Must send exact fee amount (
GM_FEEorGM_FEE_WITH_REFERRAL) - Must not have sent GM today (UTC day check)
- Cannot refer yourself or use fee recipient as referrer
Effects:
- Mints new NFT to
msg.sender - Updates
lastGMDay[msg.sender]mapping - Sends referral payment if applicable
- Sends remaining fee to fee recipient
- Emits
OnChainGMEventevent
Reverts:
AlreadySentGMToday: User already GMed todayIncorrectETHFee: Wrong fee amount sentCannotReferSelf: Attempted self-referral
Example:
// Without referral
onChainGM(address(0));
// With referral
onChainGM(0x1234...5678);Returns the number of seconds until the user can send another GM.
Parameters:
user(address): User address to check
Returns:
uint256: Seconds until next GM is allowed (0 if can GM now)
Example:
uint256 secondsRemaining = contract.timeUntilNextGM(userAddress);
// Returns 0 if user can GM now
// Returns positive number if user must waitReturns the metadata URI for a token. Returns Base64-encoded JSON data URI.
Parameters:
tokenId(uint256): Token ID to query
Returns:
string: Data URI with JSON metadata and SVG image
Reverts:
TokenDoesNotExist: Token ID doesn't exist
Example:
string memory uri = contract.tokenURI(0);
// Returns: "data:application/json;base64,eyJuYW1lIjo..."Returns the total number of NFTs minted (equal to current token ID counter).
Returns:
uint256: Total supply of GMCards
Example:
uint256 supply = contract.totalSupply();Returns the block timestamp when the NFT was minted.
Parameters:
tokenId(uint256): Token ID to query
Returns:
uint256: Unix timestamp of mint
Reverts:
TokenDoesNotExist: Token ID doesn't exist
Returns the ETH balance of the contract (for owner monitoring).
Returns:
uint256: Contract balance in wei
Updates the fee recipient address.
Parameters:
newRecipient(address): New fee recipient address (cannot be zero)
Requirements:
- Only callable by owner
newRecipientcannot beaddress(0)
Reverts:
OwnableUnauthorizedAccount: Not called by ownerInvalidAddress: Zero address provided
Updates the standard GM fee.
Parameters:
newFee(uint256): New fee amount in wei
Requirements:
- Only callable by owner
newFeemust be greater than 0newFeemust be greater thanGM_FEE_WITH_REFERRAL
Reverts:
OwnableUnauthorizedAccount: Not called by ownerInvalidFee: Invalid fee amount
Updates the GM fee when using a referral.
Parameters:
newFee(uint256): New referral fee amount in wei
Requirements:
- Only callable by owner
newFeemust be greater than 0newFeemust be less thanGM_FEE
Reverts:
OwnableUnauthorizedAccount: Not called by ownerInvalidFee: Invalid fee amount
Updates the referral reward percentage.
Parameters:
newPercent(uint256): New percentage (1-99)
Requirements:
- Only callable by owner
newPercentmust be between 1 and 99 (inclusive)
Reverts:
OwnableUnauthorizedAccount: Not called by ownerInvalidPercent: Invalid percentage
Withdraws accidentally sent ETH from the contract.
Parameters:
amount(uint256): Amount to withdraw (0 = withdraw all)to(address): Recipient address
Requirements:
- Only callable by owner
tocannot beaddress(0)- Contract must have sufficient balance
Emergency function to withdraw all ETH to fee recipient.
Requirements:
- Only callable by owner
- Fee recipient must be set
Withdraws accidentally sent ERC20 tokens.
Parameters:
token(address): ERC20 token addressamount(uint256): Amount to withdraw (0 = withdraw all)to(address): Recipient address
Emitted when a user sends a GM transaction.
event OnChainGMEvent(
address indexed sender,
address indexed referrer,
uint256 indexed tokenId
);Parameters:
sender: Address that sent the GMreferrer: Referrer address (oraddress(0)if none)tokenId: Token ID of minted NFT
Emitted when a referral payment fails.
event ReferralFailed(
address indexed referrer,
uint256 amount
);Parameters:
referrer: Address that should have received paymentamount: Amount that failed to transfer
OnChainGM V2.0 represents a significant evolution in on-chain daily rituals. By combining NFT minting, referral rewards, and upgradeable architecture, we've created a sustainable, engaging Web3 experience that brings the GM culture to the blockchain.
โจ Innovation: First-of-its-kind daily NFT minting system
๐ Security: Battle-tested OpenZeppelin contracts with comprehensive testing
๐จ User Experience: Beautiful on-chain SVG art with date stamps
๐ฑ Sustainability: Referral system and configurable fees ensure long-term viability
๐ฎ Future-Proof: Upgradeable architecture allows continuous improvement
Start your daily Web3 ritual today. Every GM transaction is:
- A permanent record on the blockchain
- A unique NFT in your collection
- A contribution to the community
- A step toward Web3 adoption
GM! Welcome to the future of on-chain engagement. ๐
distributed addresses BNB Chain: 0xB4d915FeB8b0757792435C8229D4d6AA6ab7e88d
Built with โค๏ธ by the OnChainGM Team
"Your Daily Web3 Ritual"
Made with Solidity โข OpenZeppelin โข Hardhat
โญ If you find this project useful, please consider giving it a star on GitHub!