Skip to content

Security: wkalidev/dailydrop

Security

SECURITY.md

Security

Sensitive Variables

Variable Where Risk if leaked
PRIVATE_KEY root .env Full contract control — CRITICAL
RELAYER_PRIVATE_KEY frontend/.env.local Can trigger streak updates — HIGH
CELOSCAN_API_KEY frontend/.env.local Rate limit abuse — LOW
BASESCAN_API_KEY frontend/.env.local Rate limit abuse — LOW

Reporting Vulnerabilities

Please report security vulnerabilities by opening a private GitHub security advisory at: https://github.com/wkalidev/dailydrop/security/advisories/new

Do NOT open public issues for security vulnerabilities.

Audited By

Self-audited on 2026-06-13, re-audited on 2026-07-01, and re-audited on 2026-07-18 covering contracts, API routes, SDK, and environment configuration.

The 2026-07-01 pass fixed a critical issue where /api/relayer accepted any successful transaction hash as proof of check-in without verifying it was sent by the claimed user to the real DailyDrop contract — see git history for frontend/app/api/relayer/route.ts.

The 2026-07-18 pass fixed: (1) contracts/dailydrop.clar's update-streak-from-relayer accepting an arbitrary caller-supplied new-streak with no replay/rate-limit protection — the Stacks side had never received the anti-forgery fix already applied to StreakMaster.sol; (2) contracts/dailydrop.clar's mint-initial having no supply cap, unlike DailyDrop.sol's MAX_INITIAL_SUPPLY; (3) the NEXT_PUBLIC_RELAYER_SECRET false-security issue described above.

No third-party audit yet. Use at your own risk.

Known Limitations

  • Farcaster Frame signature not verified/api/frame uses untrustedData. Full production use requires hub-based signature verification (Neynar or a self-hosted Farcaster Hub). Reflected values from untrustedData are now encoded before being embedded in the frame HTML response.
  • Leaderboard is address-based — sourced from on-chain transactions for known contracts. Not exhaustive; new users appear as they interact.
  • StreakMaster relayer requires trust — the relayer operator can submit any check-in for any user. Mitigated by CHECKIN_INTERVAL enforcement on-chain, the usedTxProofs replay prevention map, and (as of 2026-07-01) /api/relayer validating that the submitted txHash is a confirmed transaction sent by the claimed user to the real DailyDrop contract emitting a CheckIn/RewardClaimed event.
  • /api/relayer has no shared-secret gate — a prior version accepted an x-relayer-secret header sourced from NEXT_PUBLIC_RELAYER_SECRET, but any NEXT_PUBLIC_* value is inlined into the public JS bundle, so it was never actually secret and gave a false sense of protection. It has been removed (2026-07-18). Authentication is purely the on-chain receipt check: the route independently re-verifies via RPC that txHash is a successful transaction sent by the claimed user to the real DailyDrop contract, emitting a genuine CheckIn/RewardClaimed event — so a caller cannot fabricate a relay for an address they don't control, and relaying someone else's genuine check-in cannot redirect rewards away from them. Abuse/spam is bounded by the per-address rate limit (3/hour).
  • Base reward minting may be inactiveStreakMaster._triggerReward calls DailyDrop(base).mintInitial(), which requires StreakMaster to be the owner() of the Base DailyDrop contract. As of this audit, deploy.ts never performs that transferOwnership, and on-chain inspection shows the Base DailyDrop owner does not match the StreakMaster address — reward mints triggered via the relayer path on Base are likely failing silently (caught by a try/catch). Verify on-chain ownership and run transferOwnership from the current owner key if this is unintentional.

There aren't any published security advisories