A social fitness challenge app where friends commit to running goals, stake ETH or USDC, prove they completed the run, and the pot is automatically distributed to winners.
Built on Base for the MBC Hackathon β’ Base Track + Circle USDC Bounty
- Overview
- Problem & Solution
- Circle USDC Integration
- Features
- Tech Stack
- Architecture
- Quick Start
- Smart Contracts
- User Flows
- Deployed Contract Addresses
- Resources
- License
Stride is a decentralized fitness accountability platform that leverages blockchain-based financial incentives to help users achieve their fitness goals. Users create or join challenges, stake cryptocurrency (ETH or USDC), and winners who complete their goals split the pot.
- Low Fees: Transaction costs are minimal, making small stakes viable
- Fast Finality: Quick confirmation times for seamless UX
- EVM Compatible: Full Solidity support with familiar tooling
- Coinbase Ecosystem: Integration with Coinbase Smart Wallet for easy onboarding
- 80% of New Year's resolutions fail by February
- People struggle with fitness accountability
- Traditional fitness apps lack real skin-in-the-game incentives
- Cross-border participation is difficult with fiat currencies
Stride creates social accountability with financial stakes:
- Put real money on the line with friends
- Complete your fitness goal or lose your stake
- Winners are rewarded with a share of the losers' stakes
- Global participation via USDC (dollar-denominated)
This project integrates Circle's USDC stablecoin for fitness challenge staking, demonstrating a real-world payment use case on Base.
| Benefit | Description |
|---|---|
| Price Stability | Users stake a predictable dollar amount (e.g., $5 USDC) rather than volatile crypto |
| Global Accessibility | Anyone worldwide can participate with dollar-equivalent stakes |
| Low Fees on Base | Circle's native USDC on Base means minimal transaction costs |
| Real-World Payments | Demonstrates practical payment automation use case |
| Feature | Description |
|---|---|
| USDC Staking | Users stake USDC instead of ETH for challenges |
| ERC20 Approvals | Smart approval flow with "Approve Max" option |
| Prize Distribution | Winners automatically receive USDC payouts |
| Charity Donations | Unclaimed pools donated to charity in USDC |
| Testnet Faucet | Built-in MockUSDC faucet for local development |
// Uses Circle USDC (6 decimals) for all staking
IERC20 public immutable usdc;
// Create challenge with USDC stake
function createChallenge(
uint256 stakeAmount, // USDC amount (6 decimals)
uint256 duration,
string calldata description,
uint256 groupId
) external returns (uint256 challengeId)- Circle Faucet: https://faucet.circle.com/ (Base Sepolia)
- USDC Address (Base Sepolia):
0x036CbD53842c5426634e7929541eC2318f3dCF7e
- Create Challenges - Set custom fitness goals with descriptions
- Dual Currency - Stake ETH or USDC (Circle integration)
- Group Challenges - Create and join groups with friends
- Leaderboards - Track group member performance and win streaks
- Proof of Completion - Mark runs as complete on-chain
- Auto Settlement - Smart contract distributes prizes automatically
- NFT Badges - On-chain SVG achievement badges
- Early Settlement - Vote to end challenges early (consensus)
- Refund Voting - Democratic cancellation with full refunds
- Next.js 15 with TypeScript & App Router
- Tailwind CSS for modern styling
- wagmi v2 + viem for Web3 interactions
- Coinbase Wallet integration (Smart Wallet ready)
- Solidity 0.8.24 with OpenZeppelin
- Hardhat for development, testing, and deployment
- Circle USDC integration (ERC20)
- On-chain SVG NFT generation
- Base Sepolia (Testnet)
- Hardhat (Local development)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (Next.js) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β wagmi hooks β USDC Components β Challenge UI β Group UI β NFTs β
βββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βββββββββΌββββββββ
β wagmi/viem β
βββββββββ¬ββββββββ
β
βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ
β Base (L2 Ethereum) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββ β
β β StrideChallengeManagerβ β StrideUSDCChallengeManager β β
β β (ETH stakes) β β (Circle USDC stakes) β β
β ββββββββββββ¬ββββββββββββ ββββββββββββββββ¬βββββββββββββββββ β
β β β β
β β ββββββββββββββββββββββΌββββββββββββββββ β
β ββββββββββΊβ StrideGroups βββββββββββββββββ β
β β (Leaderboards & β β
β β Group Management) β β
β ββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ β
β β SimpleBadgeNFT β β Circle USDC Token (ERC20) β β
β β (On-chain SVG) β β 0x036CbD53842c5426634e7929... β β
β ββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Node.js 18+
- A wallet with Base Sepolia ETH (Faucet)
- Testnet USDC from Circle Faucet
# Clone the repository
git clone https://github.com/your-username/stride.git
cd stride
# Install frontend dependencies
npm install
# Install contract dependencies
cd contracts && npm install && cd ..cd contracts
# Start Hardhat node (keep this running)
npx hardhat nodecd contracts
# Deploy all contracts including MockUSDC
npx hardhat run scripts/deployAll.ts --network localhostYou'll see output like:
π Contract Addresses:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β StrideChallengeManager (ETH): 0x3Aa5ebB10DC797CAC828524...β
β StrideGroups: 0xc6e7DF5E7b4f2A278906862...β
β SimpleBadgeNFT: 0x4ed7c70F96B99c776995fB6...β
β USDC Token: 0xa85233C63b9Ee964Add6F2c...β
β StrideUSDCChallengeManager: 0x4A679253410272dd5232B3F...β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Create .env.local in the project root:
# Enable local development mode
NEXT_PUBLIC_LOCAL_DEV=truenpm run dev-
Add Hardhat Network to MetaMask:
- Network Name:
Hardhat - RPC URL:
http://127.0.0.1:8545 - Chain ID:
31337 - Currency Symbol:
ETH
- Network Name:
-
Import a test account from Hardhat (use one of the private keys shown when starting the node)
Create contracts/.env:
PRIVATE_KEY=your_wallet_private_key
BASE_SEPOLIA_RPC=https://sepolia.base.orgcd contracts
# Deploy all contracts
npx hardhat run scripts/deployAll.ts --network baseSepoliaUpdate .env.local:
# Remove local dev flag for production
# NEXT_PUBLIC_LOCAL_DEV=true
# Contract addresses from deployment
NEXT_PUBLIC_CONTRACT_ADDRESS=0x...
NEXT_PUBLIC_GROUPS_CONTRACT_ADDRESS=0x...
NEXT_PUBLIC_NFT_CONTRACT_ADDRESS=0x...
NEXT_PUBLIC_USDC_CONTRACT_ADDRESS=0x...
NEXT_PUBLIC_USDC_ADDRESS=0x036CbD53842c5426634e7929541eC2318f3dCF7e| Contract | Description |
|---|---|
StrideChallengeManager.sol |
ETH-based fitness challenges |
StrideUSDCChallengeManager.sol |
Circle USDC-based challenges |
StrideGroups.sol |
Group management & leaderboards |
SimpleBadgeNFT.sol |
On-chain SVG achievement badges |
MockUSDC.sol |
Test USDC token for local development |
function createChallenge(
uint256 stakeAmount,
uint256 duration,
string calldata description,
uint256 groupId
) external payable returns (uint256 challengeId)function joinChallenge(uint256 challengeId) external payablefunction markCompleted(uint256 challengeId) externalfunction settleChallenge(uint256 challengeId) external- User enters stake amount in the UI
- Frontend checks current USDC allowance
- If insufficient, prompts for approval transaction
- After approval, user can stake USDC
- Contract uses
SafeERC20.safeTransferFrom()for security
| Scenario | Action |
|---|---|
| Winners exist | Split pool equally among completers |
| No winners | Refund all participants (for challenge cancellation via unanimous vote) |
| No winners (timeout) | 10% to charity, 90% refunded |
- Connect wallet
- Navigate to a group or create one
- Click "Create Challenge"
- Select USDC as currency
- Approve USDC spending (one-time or per-challenge)
- Set description, duration, and stake amount
- Submit transaction
- Browse available challenges
- Click "Join Challenge"
- Approve USDC if needed
- Confirm transaction
- Complete your fitness goal IRL
- Click "I Finished My Run!"
- Wait for challenge deadline
- Anyone can click "Settle" to distribute prizes
| Contract | Address |
|---|---|
| StrideChallengeManager | TBD after deployment |
| StrideUSDCChallengeManager | TBD after deployment |
| StrideGroups | TBD after deployment |
| SimpleBadgeNFT | TBD after deployment |
| Circle USDC | 0x036CbD53842c5426634e7929541eC2318f3dCF7e |
Run npx hardhat run scripts/deployAll.ts --network localhost to get fresh addresses.
- Base Docs: https://docs.base.org/
- Base Sepolia Faucet: https://www.alchemy.com/faucets/base-sepolia
- BaseScan: https://sepolia.basescan.org/
- Developer Docs: https://developers.circle.com/
- USDC on Base: https://www.circle.com/en/usdc-multichain/base
- Testnet Faucet: https://faucet.circle.com/
- Bridge Kit: https://developers.circle.com/w3s/bridge-kit
| Property | Value |
|---|---|
| Network | Base Sepolia (Testnet) |
| Chain ID | 84532 |
| RPC URL | https://sepolia.base.org |
| Explorer | https://sepolia.basescan.org |
| USDC | 0x036CbD53842c5426634e7929541eC2318f3dCF7e |
MIT
Built for MBC Hackathon 2025 β’ Powered by Circle USDC β’ Built on Base