Wallet Connection Issues
Assuming wallet is always connected
Not handling disconnected state leads to crashes and poor UX.
Not handling chain switching
Users switching networks in wallet breaks app if not handled.
Only supporting one wallet
MetaMask-only apps exclude mobile users and hardware wallet users.
Not persisting connection state
Users have to reconnect wallet on every page refresh.
Blocking UI during wallet prompts
User cannot do anything while waiting for wallet signature.
Transaction Handling
Not showing transaction status
Users don't know if transaction succeeded, failed, or is pending.
No gas estimation before send
Transactions fail due to insufficient gas without warning.
Ignoring transaction reverts
Silent failures leave users confused about what happened.
Not handling stuck transactions
Low gas transactions can hang indefinitely.
Displaying raw error messages
Technical revert strings are meaningless to users.
State Management
Polling too frequently
Excessive RPC calls hit rate limits and waste resources.
Not caching blockchain data
Re-fetching same data on every render wastes RPC calls.
Stale data after transactions
UI shows old balances/state after user's transaction confirms.
Mixing local and chain state incorrectly
Local state can diverge from blockchain causing confusion.
Not handling block reorgs
Confirmed transactions can be undone in reorgs.
Security Problems
Exposing private keys in frontend
Private keys in client-side code can be stolen.
Not validating input before signing
Users might sign malicious transactions from manipulated UI.
Trusting URL parameters blindly
Phishing attacks can manipulate transaction parameters via URL.
No phishing protection
Users can be tricked by lookalike domains.
Storing sensitive data in localStorage
localStorage is accessible to any script on the domain.
UX Mistakes
No mobile responsiveness
Many users access dApps via mobile wallet browsers.
Complex onboarding for new users
Requiring wallet setup immediately loses potential users.
No loading states
Blockchain operations are slow. Empty states confuse users.
Displaying raw addresses
0x742d35Cc6634C0532925a3b844Bc9e7595f0ab3 is unreadable.
Not explaining gas
New users don't understand why they need ETH for transactions.
Development Practices
Not testing with real wallets
Mocked wallets behave differently than MetaMask.
Hardcoding contract addresses
Makes deployment to different networks painful.
Using outdated libraries
Old versions of ethers/web3 have bugs and security issues.
No error boundaries
One error crashes entire app instead of just affected component.
Ignoring TypeScript types
Using 'any' types leads to runtime errors.
Key Recommendations
Most frontend exploits target the user, not the code. Think like a phisher.
Test with multiple wallets. MetaMask behavior differs from WalletConnect.
Log client-side errors to Sentry. Users will not report bugs.