# Frontend Rewards
Earn rewards by building frontends and referring users to the JuiceDollar ecosystem.
The JuiceDollar system includes a built-in reward mechanism for frontend operators and referrers. Anyone can register a frontend code and earn a share of the activity generated through their interface.
# How It Works
The Frontend Gateway tracks user activity and attributes rewards to registered frontend codes:
User Action → Frontend Code → Reward Accrued → Withdraw Anytime
# Reward Sources
Frontend operators earn rewards from three types of user activity:
| Activity | Reward Rate | Description |
|---|---|---|
| JUICE Investment/Redemption | 1% of volume | When users buy or sell JUICE |
| Savings Interest | 5% of interest earned | When users earn interest on savings |
| Position Interest | 5% of interest paid | When borrowers pay interest |
# Example Earnings
Scenario: Your frontend facilitates:
- 100,000 JUSD invested in JUICE → 1,000 JUSD reward
- Users earn 5,000 JUSD in savings interest → 250 JUSD reward
- Borrowers pay 10,000 JUSD in position interest → 500 JUSD reward
Total: 1,750 JUSD in rewards
# Registering a Frontend Code
# Step 1: Choose Your Code
A frontend code is a bytes32 identifier. You can create one from any string:
// Example: Convert string to bytes32
const frontendCode = ethers.utils.formatBytes32String("myapp");
// Result: 0x6d79617070000000000000000000000000000000000000000000000000000000
Requirements:
- Must be unique (not already registered)
- Cannot be the zero bytes32
- First come, first served
# Step 2: Register On-Chain
Call the registration function:
function registerFrontendCode(bytes32 frontendCode) external returns (bool)
Contract: FrontendGateway (Mainnet (opens new window) | Testnet (opens new window))
# Step 3: Integrate Into Your Frontend
Pass your frontend code when users interact with the protocol:
// Investment with frontend code
await frontendGateway.invest(amount, expectedShares, frontendCode);
// Savings with frontend code
await savingsGateway.save(amount, frontendCode);
// Position opening with frontend code
await mintingHubGateway.openPosition(...params, frontendCode);
# Collecting Rewards
# Check Your Balance
View accumulated rewards:
function frontendCodes(bytes32 code) external view returns (
uint256 balance, // Accumulated rewards
address owner // Code owner
)
# Withdraw Rewards
Claim your rewards at any time:
// Withdraw to your own address
function withdrawRewards(bytes32 frontendCode) external returns (uint256)
// Withdraw to a different address
function withdrawRewardsTo(bytes32 frontendCode, address to) external returns (uint256)
Important: Rewards are paid from the equity pool. If equity is very low, withdrawals may be limited.
# Transferring Ownership
Frontend codes can be transferred to a new owner:
function transferFrontendCode(bytes32 frontendCode, address to) external returns (bool)
This is useful for:
- Selling your frontend business
- Transferring to a multi-sig
- Changing operational wallets
# Gateway Contracts
The reward system uses specialized "Gateway" contracts that extend the base functionality:
| Base Contract | Gateway Version | Added Feature |
|---|---|---|
| MintingHub | MintingHubGateway | Tracks position interest |
| Savings | SavingsGateway | Tracks savings interest |
| Equity | (via FrontendGateway) | Tracks investments |
# Why Gateways?
The gateway pattern allows:
- Backwards compatibility: Base contracts work without frontend codes
- Optional participation: Users can interact directly without rewards tracking
- Upgradeable rewards: Fee rates can be adjusted via governance
# Fee Rate Governance
The reward rates can be modified by qualified JUICE holders:
# Current Rates
| Parameter | Rate | PPM Value |
|---|---|---|
| Investment Fee | 1% | 10,000 |
| Savings Fee | 5% | 50,000 |
| Minting Fee | 5% | 50,000 |
# Proposing Changes
function proposeChanges(
uint24 newFeeRatePPM_, // Investment fee (max 2%)
uint24 newSavingsFeeRatePPM_, // Savings fee (max 100%)
uint24 newMintingFeeRatePPM_, // Minting fee (max 100%)
address[] calldata helpers // Vote delegation helpers
) external
Requirements:
- Caller must have ≥2% voting power
- Investment fee capped at 2% (20,000 PPM)
- 7-day timelock before execution
# Executing Changes
After 7 days:
function executeChanges() external
# Integration Guide
# For Web Frontends
import { ethers } from 'ethers';
const FRONTEND_CODE = ethers.utils.formatBytes32String("myapp");
// Mainnet addresses
const FRONTEND_GATEWAY = "0x3090a89A1fF5DC99117BE655599e5491A0BaBB92";
const SAVINGS_GATEWAY = "0x22FE239892eBC8805DA8f05eD3bc6aF75332b60b";
const MINTING_HUB_GATEWAY = "0x1a20B160bf546774246C7920939E6e7Ac0f88b8e";
// Testnet addresses (for development)
// const FRONTEND_GATEWAY = "0xd824b7d36594Fc3088B1D91a79F34931AA2a15D0";
// const SAVINGS_GATEWAY = "0x54430781b33581CE2b0DBD837CA66113BeEEFD8e";
// const MINTING_HUB_GATEWAY = "0x5fC684074fBaAE37Eb68d3e48D85f485CE5060F8";
// Investment with rewards
async function investWithRewards(amount, expectedShares) {
const gateway = new ethers.Contract(FRONTEND_GATEWAY, abi, signer);
return gateway.invest(amount, expectedShares, FRONTEND_CODE);
}
// Savings with rewards
async function saveWithRewards(amount) {
const savings = new ethers.Contract(SAVINGS_GATEWAY, abi, signer);
return savings.save(amount, FRONTEND_CODE);
}
// Position opening with rewards
async function openPositionWithRewards(params) {
const hub = new ethers.Contract(MINTING_HUB_GATEWAY, abi, signer);
return hub.openPosition(...params, FRONTEND_CODE);
}
# Tracking User Activity
The lastUsedFrontendCode mapping tracks which frontend code a user last interacted with:
function lastUsedFrontendCode(address user) external view returns (bytes32)
This enables:
- Persistent referral attribution
- User analytics
- Loyalty programs
# Contract Addresses
# Mainnet (Chain ID: 4114)
| Contract | Address | Purpose |
|---|---|---|
| FrontendGateway | 0x3090a89A1fF5DC99117BE655599e5491A0BaBB92 (opens new window) | Core reward tracking |
| MintingHubGateway | 0x1a20B160bf546774246C7920939E6e7Ac0f88b8e (opens new window) | Position rewards |
| SavingsGateway | 0x22FE239892eBC8805DA8f05eD3bc6aF75332b60b (opens new window) | Savings rewards |
# Testnet (Chain ID: 5115)
| Contract | Address | Purpose |
|---|---|---|
| FrontendGateway | 0xd824b7d36594Fc3088B1D91a79F34931AA2a15D0 (opens new window) | Core reward tracking |
| MintingHubGateway | 0x5fC684074fBaAE37Eb68d3e48D85f485CE5060F8 (opens new window) | Position rewards |
| SavingsGateway | 0x54430781b33581CE2b0DBD837CA66113BeEEFD8e (opens new window) | Savings rewards |
# Events
Monitor reward activity through these events:
// Frontend code registered
event FrontendCodeRegistered(address owner, bytes32 frontendCode);
// Code ownership transferred
event FrontendCodeTransferred(address from, address to, bytes32 frontendCode);
// Rewards withdrawn
event FrontendCodeRewardsWithdrawn(address to, uint256 amount, bytes32 frontendCode);
// Reward accrued from investment
event InvestRewardAdded(bytes32 frontendCode, address user, uint256 amount, uint256 reward);
// Reward accrued from redemption
event RedeemRewardAdded(bytes32 frontendCode, address user, uint256 amount, uint256 reward);
// Reward accrued from savings interest
event SavingsRewardAdded(bytes32 frontendCode, address saver, uint256 interest, uint256 reward);
// Reward accrued from position interest
event PositionRewardAdded(bytes32 frontendCode, address position, uint256 amount, uint256 reward);
# Best Practices
Register Early: Frontend codes are first-come-first-served. Register yours before someone else takes it.
Use Meaningful Codes: Choose a code that represents your brand (e.g., your app name).
Monitor Rewards: Set up event listeners to track reward accumulation in real-time.
Secure Your Keys: The owner address controls the frontend code. Use a secure wallet or multi-sig.
Disclose to Users: Be transparent with your users about the referral system.
# FAQ
# Can I use multiple frontend codes?
Yes, you can register and manage multiple codes. This is useful for:
- Different products/interfaces
- A/B testing
- Partner programs
# What if a user doesn't use a frontend code?
They can still interact with the base contracts directly. No rewards are tracked, and the protocol works normally.
# Can frontend codes be revoked?
No. Once registered, a frontend code exists permanently. Ownership can only be transferred, not revoked.
# Are rewards taxable?
Consult a tax professional in your jurisdiction. Frontend rewards may be considered income.