Improve error handling: surface transaction errors, validate inputs, add loading states#2
Conversation
…ract - page.tsx: Surface writeContract errors/success via status banner, add input validation with try-catch around parseUnits/BigInt, add loading states to buttons, track tx confirmation, guard NaN in cost preview - contract.ts: Log console.warn when contract address falls back to zero - providers.tsx: Read WalletConnect project ID from env var instead of hardcoded placeholder, warn when missing - deploy.js: Validate deployer account exists and has balance, validate USDC address format and non-zero, print next-step instructions - FCFSCampaign.sol: Add require(_usdc != address(0)) in constructor Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
🚩 OpenZeppelin v5 used with v4 import path for ReentrancyGuard
The project depends on @openzeppelin/contracts: ^5.0.0 (per contracts/package.json), but the import at contracts/FCFSCampaign.sol:6 uses @openzeppelin/contracts/security/ReentrancyGuard.sol, which is the v4 path. In OpenZeppelin v5, ReentrancyGuard was moved to @openzeppelin/contracts/utils/ReentrancyGuard.sol. This is a pre-existing issue unrelated to this PR's one-line constructor change, but it would cause a compilation failure if ^5.0.0 resolves to an actual v5 release.
Was this helpful? React with 👍 or 👎 to provide feedback.
| functionName: 'createCampaign', | ||
| args: [tweetUrl, taskType, reward, max], | ||
| }) |
There was a problem hiding this comment.
🚩 Missing ERC20 approve flow before createCampaign
The createCampaign contract function calls usdc.safeTransferFrom(msg.sender, address(this), totalAmount) at contracts/FCFSCampaign.sol:108, which requires the caller to have previously approved the contract to spend their USDC. The frontend's handleCreate at frontend/src/app/page.tsx:139 calls createCampaign directly without first calling approve on the USDC token. The ABI in frontend/src/lib/contract.ts also doesn't include the USDC approve function (it wouldn't — that's on a separate contract). This means every createCampaign call will revert unless the user has independently approved the contract. The error handler at line 38 does catch 'ERC20: insufficient allowance', but this is a poor UX — the frontend should prompt for and execute an approval transaction first. This is a pre-existing issue not introduced by this PR, but the PR's improved error handling now makes it more visible.
(Refers to lines 139-144)
Was this helpful? React with 👍 or 👎 to provide feedback.
- Add tsconfig.json with target es2020 and @/* path alias (was missing, causing build failure on main too) - Add next.config.js (required by Next.js) - Fix providers.tsx: keep non-empty placeholder projectId to prevent RainbowKit from throwing at build time; only warn in browser context Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Summary
Previously, all
writeContractcalls in the frontend silently discarded errors — users got no feedback on rejected transactions, on-chain reverts, or invalid input. Configuration issues (missing contract address, missing WalletConnect project ID) also failed silently at runtime. The deploy script had no pre-flight checks. The build itself was broken onmaindue to missingtsconfig.json.Frontend (
page.tsx):{ error, isPending, data: txHash, reset }fromuseWriteContractand track confirmation viauseWaitForTransactionReceiptStatusMessagebanner (error/pending/success) with auto-dismissparseUnits(rewardPerUser, 6)andBigInt(maxParticipants)in try-catch with user-friendly messagesextractErrorMessage()maps common contract revert strings to human-readable textFrontend (
contract.ts):console.warnwhenNEXT_PUBLIC_CONTRACT_ADDRESSis unset and falls back to zero address.Frontend (
providers.tsx): ReadNEXT_PUBLIC_WALLETCONNECT_PROJECT_IDfrom env with a non-empty placeholder fallback (required by RainbowKit at build time); warn in browser when using placeholder.Frontend config (new files): Add missing
tsconfig.json(target es2020,@/*path alias) andnext.config.js— fixes pre-existing build failure where@/lib/contractcouldn't resolve.Deploy script (
deploy.js): Validate signer exists, deployer has non-zero balance, USDC address is valid and non-zero before deploying. Print next-step instructions on success.Smart contract (
FCFSCampaign.sol):require(_usdc != address(0))in constructor.Link to Devin session: https://app.devin.ai/sessions/9292c3c9be21402d9a8e57b5f85f099f
Requested by: @fcfsprojects