Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions context/Merch MVP_ Testing Strategy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# **Project: Merch MVP Testing Strategy**

This strategy focuses on validating the **low-friction UX** and the **monetization conversion loop** on the Base Sepolia testnet, ensuring the Basic Merch SBT is **retained** after upgrade.

## **1\. Smart Contract Testing (Foundry)**

| Test Area | Key Scenario | Pass Condition |
| :---- | :---- | :---- |
| **SBT Minting** | Standard minting of BasicMerch to a wallet. | SBT is minted; the transaction requires and consumes a minimal gas fee. |
| **Premium Companion Mint** | Wallet calls PremiumMerch.mintCompanion() with sufficient ETH and a valid SBT ID. | **SBT IS RETAINED** in the user's wallet; ERC-721 is minted; fee is split correctly. |
| **Access Control** | Attempt to mint Premium Merch without owning the corresponding Basic SBT. | Transaction is reverted with a custom error message. |
| **Fee Calculation** | Test upgrade payment with edge cases (slightly overpaid/underpaid). | Underpaid reverts; Overpaid succeeds, excess is returned to the user or treasury as defined. |

## **2\. Backend/API Testing**

| Test Area | Key Scenario | Pass Condition |
| :---- | :---- | :---- |
| **Verification** | POST /verify-code with a used/expired code. | Returns HTTP 400 with status code CLAIM\_INVALID. |
| **Off-Chain Reserve (Happy Path)** | POST /claim-offchain with valid code and email. | Returns HTTP 200 with reservationId; DB reflects reserved status. |
| **Redemption Update** | Minting the SBT after a reservation should mark the DB record as "CLAIMED." | Backend logic confirms SBT mint and updates off-chain status. |
| **EAS Attestation** | POST /attest-claim with a verified txHash for a Premium Mint. | Backend successfully issues EAS attestation with isPremium=true and sbtTokenId recorded. |
| **Security** | POST request to any endpoint without the X-API-KEY header. | Returns HTTP 401 (Unauthorized). |

## **3\. Frontend/UX Integration Testing**

| Test Area | Key Scenario | Pass Condition |
| :---- | :---- | :---- |
| **Off-Chain Reservation UX** | New user reserves claim using an email address. | UI shows success message, prompting user to check email/return later. No wallet connection required. |
| **Redemption Flow** | User returns, connects wallet, and mints a previously reserved claim. | Mini-App pulls reservation data from DB/Backend and mints SBT to the connected wallet, consuming the reservation and requiring gas. |
| **Dual Asset Display** | User successfully claims both the Basic SBT and the Premium ERC-721. | **Both tokens are visible** in the collection view, with clear labeling (POA vs. Tradable). |
| **Conversion Flow** | User successfully completes the Premium Mint transaction. | The Basic NFT **REMAINS VISIBLE** in the wallet; the new Premium NFT appears. |
| **Wallet Interaction** | User attempts both SBT mint and ERC-721 upgrade with an empty wallet balance. | Both transactions correctly prompt the user's wallet for funds and fail if the wallet is empty. |

47 changes: 24 additions & 23 deletions context/Merch_MVP_ Smart Contract Specification.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
# **Merch MVP: Smart Contract Specification**
# **Project: Merch MVP Smart Contract Specification**

This document details the essential logic and public interfaces for the two core token contracts and the Ethereum Attestation Service (EAS) implementation for the MVP deployed on Base Sepolia.
This specification details the design and core functions of the smart contracts for deployment on the **Base Sepolia Testnet**.

### **1\. ERC-4973: Basic Merch SBT Contract (BasicMerch.sol)**
## **1\. Basic Merch Contract (BasicMerch.sol)**

This contract handles the non-transferable proof of attendance (Free Tier).
| Standard | ERC-4973 (Soulbound Token \- SBT) |
| :---- | :---- |
| **Purpose** | **PERMANENT, VISIBLE PROOF OF ATTENDANCE (POA).** Non-transferable, low-cost token. |
| **Key Functions** | **mintSBT(address \_to, uint256 \_eventId, string memory \_tokenURI, bytes memory \_signature):** **CRITICAL CHANGE:** This function is now **public** (allowing anyone to pay gas) but requires a unique signature from the Backend Issuer wallet to validate the mint is authorized. |
| | getSBTByEvent(address \_owner, uint256 \_eventId): Lookup the SBT ID for a given user/event. |
| **Access Control** | The function uses ecrecover to ensure the submitted \_signature was generated by the trusted Backend Issuer wallet for that specific event and user. **This makes the function public/callable by anyone while maintaining security.** |

| Function | Type | Description | Access Control |
| :---- | :---- | :---- | :---- |
| mintSBT(address \_to, string memory \_tokenURI) | External | **Sponsored Function.** Mints a new SBT to \_to. This is the zero-cost entry point for the user. | Only callable by a whitelisted address (e.g., the Backend API/Minter Role). |
| burnSBT(uint256 \_tokenId) | External | **Core Logic.** Allows the Premium NFT contract to burn the SBT during the upgrade process. | Only callable by the PremiumMerch.sol contract address. |
| isApprovedOrOwner(address \_spender, uint256 \_tokenId) | Public/View | Required for the ERC-721 contract to perform the burn on the user's behalf. | Any caller. |
## **2\. Premium Merch Contract (PremiumMerch.sol)**

### **2\. ERC-721: Premium Merch NFT Contract (PremiumMerch.sol)**
| Standard | ERC-721 (Transferable NFT) |
| :---- | :---- |
| **Purpose** | Tradable, high-value digital collectible (the 'premium' companion asset and revenue source). |
| **Key Functions** | **mintCompanion(uint256 \_sbtId, string memory \_tokenURI): CRITICAL MONETIZATION FUNCTION.** |
| **Logic** | 1\. Accepts a payment (msg.value in test ETH). 2\. **VERIFIES OWNERSHIP** of \_sbtId on the BasicMerch contract (caller must own the SBT). 3\. Mints a new ERC-721 to the user. 4\. Transfers the payment (minus Organizer share) to the Merch Treasury. |
| **Access Control** | The mintCompanion function must ensure the caller owns the prerequisite \_sbtId before proceeding. The Treasury/Organizer addresses must be configurable. |

This contract handles the tradable collectible, monetization, and upgrade logic (Paid Tier).
## **3\. EAS Attestation Logic**

| Function | Type | Description | Access Control |
| :---- | :---- | :---- | :---- |
| upgradeSBT(uint256 \_sbtId, address \_organizer) | **Payable External** | **Monetization Logic.** The core function to upgrade a Basic Merch SBT to a Premium ERC-721. Requires a specific amount of test ETH/USDC sent with the transaction. | Any user holding a valid SBT. |
| **Upgrade Logic (Internal)** | Internal (in upgradeSBT) | **1\. Fee Check:** Confirms msg.value meets the required test upgrade fee. **2\. Burn SBT:** Calls BasicMerch.burnSBT(\_sbtId). **3\. Fee Split:** Distributes msg.value to the mock Treasury and the \_organizer address based on the predefined split (e.g., 37.5% / 62.5%). **4\. Mint ERC-721:** Mints a new ERC-721 to msg.sender. | N/A |
| setBaseURI(string memory \_uri) | Only Owner | Sets the base URI for the collectible metadata. | Contract Owner. |

### **3\. Ethereum Attestation Service (EAS)**

| Element | Specification | Purpose |
| :---- | :---- | :---- |
| **Attestation Schema** | bytes32 event\_id, uint64 timestamp, bool is\_premium\_upgrade | Data structure to prove *what* was attended and *when*, with a flag to denote the upgrade status. |
| **Issuance Points** | Executed in two places: | 1\. **After BasicMerch.mintSBT():** Records the foundational attendance proof (is\_premium\_upgrade \= false). 2\. **After PremiumMerch.upgradeSBT():** Records the upgrade action (is\_premium\_upgrade \= true). |
| Standard | Ethereum Attestation Service (EAS) |
| :---- | :---- |
| **Schema** | Custom schema registered on Base Sepolia: **MerchAttendance** |
| **Data Fields** | eventId (bytes32), timestamp (uint256), isPremium (bool), **sbtTokenId (uint256)** (New Field to link records) |
| **Attester** | The dedicated **Backend Attester Wallet** (pre-funded). |
| **Trigger** | Executed by the **Backend API** upon successful on-chain transaction confirmation (Mint of SBT *or* Mint of ERC-721). |
| **Role** | Provides the verifiable, immutable record of the attendance claim, decoupling historical proof from the tradable asset's status. |

66 changes: 32 additions & 34 deletions context/Merch_MVP_ Testing Strategy.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
# **Merch MVP: Testing Strategy**

Testing for the Merch MVP is focused on validating the zero-gas UX and the security of the monetization logic. All tests should be executed on **Base Sepolia**.

### **1\. Smart Contract Unit Tests (Foundry)**

| Test Case | Contract | Objective | Expected Outcome |
| :---- | :---- | :---- | :---- |
| **Mint Success** | BasicMerch (SBT) | Verify the mintSBT function is callable only by the Minter role. | Mint succeeds; token is non-transferable. |
| **SBT Burn Access** | BasicMerch (SBT) | Verify that only the PremiumMerch contract can call burnSBT. | Burn by user/other contract fails; burn by PremiumMerch succeeds. |
| **Upgrade Fee Check** | PremiumMerch (ERC-721) | Test upgradeSBT with insufficient msg.value. | Transaction reverts with insufficient fee error. |
| **Upgrade E2E Logic** | PremiumMerch (ERC-721) | Test successful upgrade execution. | SBT is burned; new ERC-721 is minted to user; **Fee is split correctly** to Treasury/Organizer addresses. |
| **Double Upgrade** | PremiumMerch (ERC-721) | Attempt to upgrade the same SBT twice. | Transaction reverts due to failure to burn the non-existent SBT. |

### **2\. Integration Tests**

These tests validate the interaction between on-chain and off-chain components.

| Test Case | Components | Objective | Expected Outcome |
| :---- | :---- | :---- | :---- |
| **Paymaster Sponsorship** | BasicMerch \+ Paymaster | Verify a mintSBT transaction is executed with the gas cost covered by the Paymaster service. | Transaction succeeds; gas fee paid by the Paymaster (verified on block explorer/CDP dashboard). |
| **EAS Attestation Trigger** | BasicMerch \+ Backend API | Verify the EAS record is created after the SBT mint. | SBT is minted; a corresponding Attestation with the correct schema data is found on EAS Scan. |
| **Monetization Oracle** | Frontend \+ Backend API | Verify the frontend accurately calculates and displays the required ETH/USDC fee. | Frontend accurately calculates required value based on test oracle rates before transaction submission. |

### **3\. End-to-End (E2E) User Flow Tests**

These tests replicate the live Mini-App experience in a staging environment.

| Test Case | Scenario | Focus | Required Verification |
| :---- | :---- | :---- | :---- |
| **E2E Claim (Happy Path)** | User claims Merch with a valid code. | Zero-Gas UX | **No gas prompt shown.** SBT appears in the wallet/Merch Viewer screen. |
| **E2E Upgrade (Happy Path)** | User upgrades their claimed SBT. | Monetization Logic | User is prompted for a transaction and pays the fee. Old SBT vanishes; new ERC-721 appears. |
| **E2E Negative (Invalid Code)** | User attempts to claim with a forged/used code. | Security/Code Verification | Backend API rejects the code; no transaction is submitted. |
| **E2E Insufficient Funds** | User attempts to upgrade without enough ETH/USDC. | Upgrade UX | Wallet prompts with an "Insufficient Funds" error; transaction fails before execution. |
# **Project: Merch MVP Testing Strategy**

This strategy focuses on validating the **low-friction UX** and the **monetization conversion loop** on the Base Sepolia testnet, ensuring the Basic Merch SBT is **retained** after upgrade.

## **1\. Smart Contract Testing (Hardhat/Foundry)**

| Test Area | Key Scenario | Pass Condition |
| :---- | :---- | :---- |
| **SBT Minting** | Standard minting of BasicMerch to a wallet. | SBT is minted; the transaction requires and consumes a minimal gas fee. |
| **Premium Companion Mint** | Wallet calls PremiumMerch.mintCompanion() with sufficient ETH and a valid SBT ID. | **SBT IS RETAINED** in the user's wallet; ERC-721 is minted; fee is split correctly. |
| **Access Control** | Attempt to mint Premium Merch without owning the corresponding Basic SBT. | Transaction is reverted with a custom error message. |
| **Fee Calculation** | Test upgrade payment with edge cases (slightly overpaid/underpaid). | Underpaid reverts; Overpaid succeeds, excess is returned to the user or treasury as defined. |

## **2\. Backend/API Testing**

| Test Area | Key Scenario | Pass Condition |
| :---- | :---- | :---- |
| **Verification** | POST /verify-code with a used/expired code. | Returns HTTP 400 with status code CLAIM\_INVALID. |
| **Off-Chain Reserve (Happy Path)** | POST /claim-offchain with valid code and email. | Returns HTTP 200 with reservationId; DB reflects reserved status. |
| **Redemption Update** | Minting the SBT after a reservation should mark the DB record as "CLAIMED." | Backend logic confirms SBT mint and updates off-chain status. |
| **EAS Attestation** | POST /attest-claim with a verified txHash for a Premium Mint. | Backend successfully issues EAS attestation with isPremium=true and sbtTokenId recorded. |
| **Security** | POST request to any endpoint without the X-API-KEY header. | Returns HTTP 401 (Unauthorized). |

## **3\. Frontend/UX Integration Testing**

| Test Area | Key Scenario | Pass Condition |
| :---- | :---- | :---- |
| **Off-Chain Reservation UX** | New user reserves claim using an email address. | UI shows success message, prompting user to check email/return later. No wallet connection required. |
| **Redemption Flow** | User returns, connects wallet, and mints a previously reserved claim. | Mini-App pulls reservation data from DB/Backend and mints SBT to the connected wallet, consuming the reservation and requiring gas. |
| **Dual Asset Display** | User successfully claims both the Basic SBT and the Premium ERC-721. | **Both tokens are visible** in the collection view, with clear labeling (POA vs. Tradable). |
| **Conversion Flow** | User successfully completes the Premium Mint transaction. | The Basic NFT **REMAINS VISIBLE** in the wallet; the new Premium NFT appears. |
| **Wallet Interaction** | User attempts both SBT mint and ERC-721 upgrade with an empty wallet balance. | Both transactions correctly prompt the user's wallet for funds and fail if the wallet is empty. |

Loading
Loading