[Phase 3] Risk Assessment & Security Warnings for Transaction Simulation
- Dominant language
- JavaScript
- Stars
- 2
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Overview
Implement risk assessment and security warnings to detect potentially malicious or risky transactions and alert users before they sign.
## Parent Issue
#140 - Implement Transaction Simulation for Enhanced Wallet Security
## Dependencies
- Requires #141 (Phase 1: Basic On-Chain Simulation)
- Requires #142 (Phase 2: Balance Change Preview)
## Background
With simulation results and balance changes available, we can now analyze transactions for common attack patterns and warn users about potential risks.
## Risk Categories
| Risk Level | Color | Action |
|------------|-------|--------|
| **Low** | Green | No warning, proceed normally |
| **Medium** | Yellow | Show warning, allow proceed |
| **High** | Orange | Show warning, require acknowledgment |
| **Critical** | Red | Block transaction, require explicit override |
## Risk Detection Rules
### 1. Unlimited Token Approvals
```javascript
function detectUnlimitedApproval(approvalChanges) {
const MAX_UINT256 = 2n ** 256n - 1n
for (const approval of approvalChanges) {
if (BigInt(approval.newAllowance) === MAX_UINT256) {
return {
type: 'UNLIMITED_APPROVAL',
severity: 'high',
title: 'Unlimited Token Approval',
message: `This transaction grants unlimited access to your ${approval.symbol} tokens.`,
details: `Spender: ${approval.spenderName || approval.spender}`,
recommendation: 'Consider approving only the exact amount needed.',
}
}
}
return null
}
```
### 2. Unverified Contract Interaction
```javascript
async function detectUnverifiedContract(targetAddress, provider) {
// Check Etherscan for verified source code
const isVerified = await checkContractVerification(targetAddress)
if (!isVerified) {
return {
type: 'UNVERIFIED_CONTRACT',
severity: 'medium',
title: 'Unverified Contract',
message: 'This contract has not been verified on Etherscan.',
details: `Contract: ${targetAddress}`,
recommendation: 'Proceed with caution. Verified contracts are more trustworthy.',
}
}
return null
}
```
### 3. Draining Transaction (Send without Receive)
```javascript
function detectDrainingTransaction(balanceChanges) {
const losses = balanceChanges.filter(c => !c.isPositive)
const gains = balanceChanges.filter(c => c.isPositive)
// Significant loss with no gain (excluding gas)
if (losses.length > 0 && gains.length === 0) {
const totalLossUSD = calculateTotalUSD(losses)
if (totalLossUSD > 10) { // Threshold: $10
return {
type: 'DRAINING_TRANSACTION',
severity: 'critical',
title: 'Potential Draining Transaction',
message: 'This transaction sends assets but you receive nothing in return.',
details: `You will lose: ${formatLosses(losses)}`,
recommendation: 'This could be a phishing attack. Verify the destination carefully.',
}
}
}
return null
}
```
### 4. First-Time Contract Interaction
```javascript
async function detectFirstTimeInteraction(accountAddress, targetContract, provider) {
// Check transaction history for previous interactions
const hasInteracted = await checkPreviousInteractions(accountAddress, targetContract)
if (!hasInteracted) {
return {
type: 'FIRST_INTERACTION',
severity: 'low',
title: 'First-Time Interaction',
message: 'You have never interacted with this contract before.',
details: `Contract: ${targetContract}`,
recommendation: 'Double-check you are on the correct website.',
}
}
return null
}
```
### 5. Honeypot Token Detection
```javascript
async function detectHoneypotToken(tokenAddress, simulationResult) {
// If we're receiving a token, try to simulate selling it
const gains = simulationResult.balanceChanges.filter(c => c.isPositive && c.token !== 'ETH')
for (const gain of gains) {
// Simulate a transfer of the received token
const canTransfer = await simulateTokenTransfer(gain.token, gain.after)
if (!canTransfer) {
return {
type: 'HONEYPOT_TOKEN',
severity: 'critical',
title: 'Potential Honeypot Token',
message: `The token ${gain.symbol} may prevent you from selling or transferring.`,
details: 'Transfer simulation failed.',
recommendation: 'Do not proceed. This token may be a scam.',
}
}
}
return null
}
```
### 6. Large Value Transaction
```javascript
function detectLargeValueTransaction(balanceChanges, thresholdUSD = 1000) {
const totalValueUSD = calculateTotalValueUSD(balanceChanges)
if (totalValueUSD > thresholdUSD) {
return {
type: 'LARGE_VALUE',
severity: 'medium',
title: 'High Value Transaction',
message: `This transaction involves ${formatUSD(totalValueUSD)} in assets.`,
details: 'Please review all details carefully.',
recommendation: 'Consider splitting into smaller transactions.',
}
}
return null
}
```
### 7. Known Scam Address
```javascript
async function detectKnownScamAddress(addresses) {
// Check against known scam database (could use external API)
for (const address of addresses) {
const scamInfo = await checkScamDatabase(address)
if (scamInfo) {
return {
type: 'KNOWN_SCAM',
severity: 'critical',
title: 'Known Scam Address',
message: `This address has been reported as a scam: ${scamInfo.reason}`,
details: `Address: ${address}`,
recommendation: 'Do not proceed with this transaction.',
}
}
}
return null
}
```
## Tasks
### Core Risk Assessment
- [ ] Create `frontend/src/lib/riskAssessment.js`
- [ ] Implement `detectUnlimitedApproval()`
- [ ] Implement `detectUnverifiedContract()` using Etherscan API
- [ ] Implement `detectDrainingTransaction()`
- [ ] Implement `detectFirstTimeInteraction()`
- [ ] Implement `detectHoneypotToken()` (basic version)
- [ ] Implement `detectLargeValueTransaction()`
- [ ] Implement `assessTransactionRisk()` aggregator function
- [ ] Calculate overall risk level from individual detections
### UI Components
- [ ] Create `RiskWarning.jsx` component:
```
┌─────────────────────────────────────┐
│ ⚠️ HIGH RISK │
│ Unlimited Token Approval │
├─────────────────────────────────────┤
│ This transaction grants unlimited │
│ access to your USDC tokens. │
│ │
│ Spender: Unknown Contract │
│ 0x1234...5678 │
│ │
│ 💡 Consider approving only the │
│ exact amount needed. │
│ │
│ [ ] I understand the risks │
└─────────────────────────────────────┘
```
- [ ] Create `RiskSummary.jsx` for overall risk display
- [ ] Add severity-based styling (colors, icons)
- [ ] Add acknowledgment checkbox for high/critical risks
- [ ] Add "Learn More" links for each warning type
### Integration
- [ ] Run risk assessment after simulation completes
- [ ] Display warnings in SwapConfirmationScreen
- [ ] Display warnings in TransactionSender
- [ ] Block "Confirm" button for critical risks until acknowledged
- [ ] Log risk warnings for analytics (privacy-preserving)
### External Integrations (Optional)
- [ ] Integrate Etherscan API for contract verification check
- [ ] Consider scam address database integration
- [ ] Add caching for external API calls
## Files to Create
1. **`frontend/src/lib/riskAssessment.js`** - Risk detection logic
2. **`frontend/src/components/RiskWarning.jsx`** - Individual warning component
3. **`frontend/src/components/RiskSummary.jsx`** - Overall risk summary
4. **`frontend/src/styles/RiskWarning.css`** - Styling
## Files to Modify
1. **`frontend/src/lib/transactionSimulator.js`** - Add risk assessment call
2. **`frontend/src/screens/SwapConfirmationScreen.jsx`** - Display warnings
3. **`frontend/src/components/TransactionSender.jsx`** - Display warnings
## Acceptance Criteria
- [ ] Unlimited approvals are detected and flagged
- [ ] Unverified contracts show a warning
- [ ] Draining transactions (send without receive) are flagged as critical
- [ ] First-time interactions show informational warning
- [ ] Large value transactions prompt extra caution
- [ ] Warnings are color-coded by severity
- [ ] Critical risks require explicit acknowledgment
- [ ] User can still proceed after acknowledging risks
- [ ] Recommendations are helpful and actionable
## Testing
- [ ] Test unlimited approval detection (set allowance to MAX_UINT256)
- [ ] Test draining transaction detection (send ETH, receive nothing)
- [ ] Test first-time interaction warning
- [ ] Test large value warning threshold
- [ ] Test acknowledgment flow for critical risks
- [ ] Test that low-risk transactions show no warnings
## UI Mockup
### Warning Banner (High Severity)
```
┌─────────────────────────────────────────────┐
│ ⚠️ WARNINGS DETECTED │
├─────────────────────────────────────────────┤
│ │
│ 🔶 High: Unlimited Token Approval │
│ ┌───────────────────────────────────────┐ │
│ │ This grants unlimited access to your │ │
│ │ USDC tokens. │ │
│ │ │ │
│ │ 💡 Consider approving exact amount │ │
│ └───────────────────────────────────────┘ │
│ │
│ 🔵 Low: First-Time Interaction │
│ ┌───────────────────────────────────────┐ │
│ │ You've never used this contract. │ │
│ │ │ │
│ │ 💡 Verify you're on the right site │ │
│ └───────────────────────────────────────┘ │
│ │
│ ☑️ I understand and accept these risks │
│ │
│ [Cancel] [Proceed Anyway] │
└─────────────────────────────────────────────┘
```
### Risk Summary Badge
```
┌──────────────┐
│ Risk: 🟡 Med │ (shown in confirmation header)
└──────────────┘
```
## Estimated Effort
**Medium-High** - 3-4 days
## Labels
`security`, `enhancement`, `frontend`, `ux`
Contributor guide
Assessment
This issue has not been assessed yet.