# 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.

V2 ONLY

Frontend rewards are emitted exclusively by the V2 module (MintingHubGateway, SavingsGateway, FrontendGateway). The V3 module bypasses the Gateway layer and does not distribute frontend rewards. To earn rewards, route your users through V2 contracts.

# 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

  1. Register Early: Frontend codes are first-come-first-served. Register yours before someone else takes it.

  2. Use Meaningful Codes: Choose a code that represents your brand (e.g., your app name).

  3. Monitor Rewards: Set up event listeners to track reward accumulation in real-time.

  4. Secure Your Keys: The owner address controls the frontend code. Use a secure wallet or multi-sig.

  5. 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.