Withdrawal request
This site wants permission to withdraw your NFTs
Estimated changes
You're giving someone else permission to spend this amount from your account.
Spending cap: Unlimited
Spender: 0x27e14...32d24 (WBTC/ARC Swap Pair)
Method: approve
Token transfers work in 2 steps on blockchain:
Step 1: User gives smart contract permission
"Hey, this contract can use my tokens"
→ approve() function is called
Step 2: Smart contract takes tokens and executes swap
"OK, I have the tokens, executing swap"
→ swap() function is called
Reason: Security + Control
- User control - User grants permission to chosen contract only
- Not atomic - Two separate transactions
- Safety valve - Protection from malicious code
User: "I want to swap WBTC → ARC"
↓
Frontend: "Swap button clicked"
↓
MetaMask opens: "Approval required"
Message user sees:
"Withdrawal request"
"Want to withdraw your NFTs"
"Unlimited spending cap"
↓
User: "WHAT, is this asking for NFTs?" 😱
↓
Many people cancel
WHAT WE WANT (Clear) ✅
User: "I want to swap WBTC → ARC" ↓ Frontend shows: "Approval needed for swap Allowing 0x27e14...32d24 (WBTC/ARC Pair) to spend 0.00001 WBTC This is normal and safe!" ↓ MetaMask opens (same popup but user is prepared) ↓ User: "OK, this is a normal swap approval" ✓
---
## ✅ This Is Completely Normal - Why?
### Token Transfer Mechanism in DeFi
**Token transfers work in 2 steps on blockchain:**
Step 1: User gives smart contract permission "Hey, this contract can use my tokens" → approve() function is called
Step 2: Smart contract takes tokens and executes swap "OK, I have the tokens, executing swap" → swap() function is called ↓ 2 transactions complete:
- Approve (WBTC Token Contract)
- Swap (WBTC/ARC Pair)
### Why This Way?
**Reason: Security + Control**
1. **User control** - User only grants to chosen contract
2. **Not atomic** - Two separate transactions
3. **Safety valve** - Protection from malicious code
---
## 🔍 Technical Detail: Why Does It Say "NFT Withdrawal"?
### MetaMask Message is Generic
MetaMask says: "Withdrawal request" Actual operation: Token approval Message maker: MetaMask (generic template) Should say: "Approve Token Spending"
**Why this message?**
- MetaMask shows same message for all `approve()` calls
- Whether ERC20 token or NFT, template is identical
- Developers cannot customize this message
- User assumption: "Withdrawal = money is going out?" ❌ Wrong!
---
## ✅ This Approval Is Safe - Here's Why
### 1. Contract Address Is Correct
Spender: 0x27e14cfEF1a029A32F574263dce67371bce32d24 This: GenericAMMPair WBTC/ARC contract
Is the contract correct? ✓ YES - Defined in Constants ✓ YES - Deployed on testnet ✓ YES - Has source code
### 2. Token Address Is Correct
Spending from: 0x27488Db1F8F9529B5820De984262179Ad913798E This: Mock WBTC Token
Is the token correct? ✓ YES - Defined in Constants ✓ YES - Required for swap
### 3. Is Spending Cap A Problem?
Spending cap: Unlimited
ACTUAL SITUATION:
-
It says "Unlimited" but it only applies to THIS transaction!
-
Frontend approval works like this:
const approveTx = await tokenContract.approve( pairAddress, ethers.MaxUint256 // ← Unlimited );
WHY UNLIMITED?
- Setup simplicity - User doesn't want to approve every time
- Gas savings - No need to re-approve for multiple swaps
- DeFi standard - Most protocols do this
- User control - User can revoke anytime
RISK:
- Malicious contract = Could take all WBTC ❌
- But this contract is known and tested ✓
REDUCED OPTION: // Much safer but requires approval for every 2 swaps const approveTx = await tokenContract.approve( pairAddress, amountWei // Only for this transaction );
---
## 🎯 Solution: Add Warning in Frontend
### Problem: User Is Scared
**Solution: Clear explanation in the UI**
```typescript
// Add to Swap.tsx:
{approvalNeeded && (
<div className="bg-blue-900/20 border border-blue-600 p-3 rounded mb-4">
<p className="text-sm text-blue-400">
<span className="font-bold">ℹ️ Approval Required:</span>
To swap, we need permission to use your WBTC.
This is a standard DeFi operation and completely safe.
</p>
<p className="text-xs text-blue-300 mt-2">
You'll see MetaMask popup saying "Withdrawal request" -
this is normal. Just confirm to proceed.
</p>
</div>
)}
<button onClick={handleSwap}>
{approvalNeeded ? "Approve & Swap" : "Swap Now"}
</button>
We can't change the message but we can educate users:
- "Withdrawal request" is just generic text
- "Spending cap Unlimited" is safe for this contract
- Clicking "Confirm" is SAFE
Old Token Transfer:
User → Contract: "Send me 1 WBTC"
PROBLEM: Removes money from user, contract can't do anything
Modern Approve + Transfer (DeFi):
Step 1: User → Token Contract: "Approve 0x27e14... to spend 1 WBTC"
Step 2: User → Swap Contract: "Send my WBTC to 0x27e14... and give me ARC"
BENEFITS:
✓ User maintains control
✓ If contract bugs, user funds are safe
✓ Multiple transactions are traceable
SCENARIO 1: Limited Approval (Approve for each swap)
Swap 1: Approve $100 WBTC → Swap
Swap 2: Approve $100 WBTC → Swap
Swap 3: Approve $100 WBTC → Swap
PROBLEM: User sees 3 approval popups, gets confused
SCENARIO 2: Unlimited Approval (Approve once)
Approve: Unlimited WBTC → Contract
Swap 1: Swap WBTC → ARC (30 seconds)
Swap 2: Swap WBTC → ARC (30 seconds)
Swap 3: Swap WBTC → ARC (30 seconds)
BENEFIT: User approves once, swaps freely
RISK: If contract bugs, it could take all WBTC
REAL RISK: LOW because:
✓ Contract is tested
✓ Open source code available
✓ Running on testnet (not mainnet)
- ✅ Contract address: Correct
- ✅ Token address: Correct
- ✅ Network: Testnet (not mainnet)
- ✅ Source code: Available
- ✅ Deployed: Yes
- ✅ Gas fee: Reasonable
- Contract has no admin - It's locked code
- Open source - You can review the code
- Testnet only - Not real money
- User can revoke - You can revoke approval anytime
- Single purpose - Can only perform swaps
CRITICAL ⚠️
This is a testnet environment. Follow these rules:
1. NEVER use your mainnet wallet address
❌ WRONG: Import mainnet private key into MetaMask
✅ RIGHT: Create a separate testnet wallet
2. NO real assets are at risk
❌ WRONG: Think you're losing real money
✅ RIGHT: Test tokens are worthless - they're free test funds
3. Test with small amounts
RECOMMENDED AMOUNTS:
- USDC: 0.01 (less than 1 penny)
- ETH: 0.0001 (fraction of a cent)
- WBTC: 0.00001 (tiny amount)
- ARC: 0.01 (test token)
4. Testnet faucet provides unlimited funds
✓ If you run out, just get more from the faucet
✓ These tokens have zero value
✓ Experiment freely!
5. Wallet setup safety
✓ Create NEW MetaMask wallet for testnet
✓ Use a different password than mainnet
✓ Or import testnet private key only
✓ NEVER share private keys
SCENARIO A: Malicious Contract (Not Here)
Problem: What if the contract tries to steal tokens?
Reality: This contract is open source and tested
Your Safety: Testnet tokens have zero value anyway
SCENARIO B: User Forgets Network Switch
Problem: User approves but stays on wrong network
Reality: Transaction fails, nothing is sent
Your Safety: Just switch networks and try again
SCENARIO C: User Loses Access
Problem: Forgot testnet wallet password
Reality: Create a new testnet wallet
Your Safety: No real loss - it's just test tokens
THE BOTTOM LINE:
✓ You cannot lose real money
✓ Worst case: Testnet wallet is lost (costs $0)
✓ Best case: You learn how approvals work safely
// Show in Swap modal:
"Approval needed - MetaMask will show a popup
This is normal and safe. Just confirm to continue."Problem: MetaMask uses generic "Withdrawal request" message
Solution: Can criticize MetaMask but can't change it
Better: Educate users through UI
Current: MaxUint256 (Unlimited)
Better: Swap amount × 1.1 (more conservative)
Trade-off: Might need re-approval after some swaps
User Sees: Real Meaning:
"Withdrawal request" → Approval request
"Your NFTs" → Your Tokens
"Unlimited" → Safe for this contract
"Spender contract" → Swap pair contract
Before: "MetaMask popup coming - click confirm"
After: "Swap successful! 0.00001 WBTC → 0.01 ARC"
vs
Current: User gets scared and cancels
YES, 100% safe on testnet.
APPROVAL PROCESS IS SAFE BECAUSE:
✓ Contract code is open and tested
✓ Token addresses are correct
✓ Network is correct (testnet, not mainnet)
✓ No transaction limits for approved spender
✓ Testnet tokens have zero real value
ADDITIONAL TESTNET PROTECTIONS:
✓ This is NOT mainnet - no real assets
✓ Create a separate testnet wallet
✓ Test with tiny amounts (see Testnet Safety Rules)
✓ Worst case: lose access to testnet wallet ($0 loss)
METAMASK MESSAGE IS CONFUSING BUT SAFE:
✗ Generic "Withdrawal request" template
✗ "Your NFTs" doesn't apply here (it's tokens)
✗ "Unlimited" looks scary but it's safe
→ Solution: Frontend now explains everything clearly
Before you click "Swap":
WALLET & NETWORK:
✓ Using a testnet wallet (not mainnet)?
✓ Connected to Arc Testnet?
✓ Have some test gas funds (USDC)?
AMOUNTS:
✓ Swapping a reasonable amount?
(USDC 0.01, ETH 0.0001, WBTC 0.00001 recommended)
✓ Balance is sufficient?
APPROVAL UNDERSTANDING:
✓ MetaMask will show "Withdrawal request" - NORMAL
✓ There will be a red network fee warning - NORMAL
✓ You'll see 2 transactions (Approve + Swap) - NORMAL
AFTER SWAP:
✓ Transaction hash visible in explorer
✓ Balances update in UI
✓ Want to try again? Use faucet to get more test tokens
Add this warning to Frontend (Swap.tsx):
{/* Approval Warning - Comprehensive Info */}
{showApprovalWarning && (
<div className="space-y-3">
{/* Safety Info */}
<div className="bg-blue-900/20 border border-blue-600/50 p-3 rounded-lg">
<p className="text-sm text-blue-400 leading-relaxed">
<span className="font-bold">ℹ️ Token Approval Required:</span>
MetaMask will ask permission to use your tokens. This is normal and safe.
</p>
</div>
{/* Network Fee Warning */}
<div className="bg-yellow-900/20 border border-yellow-600/50 p-3 rounded-lg">
<p className="text-xs text-yellow-300 leading-relaxed">
<span className="font-bold">⚠️ Network Fee Alert:</span>
MetaMask may show a red warning during approval. This is normal -
it means MetaMask is verifying the network fee. Wait 5-10 seconds
and it will disappear automatically. Then click "Sign" to complete.
</p>
</div>
{/* Safe & Testnet Info */}
<div className="bg-green-900/20 border border-green-600/50 p-3 rounded-lg">
<p className="text-xs text-green-300 leading-relaxed">
<span className="font-bold">✓ Safe & Normal:</span>
The "Withdrawal request" message is MetaMask's generic template.
It's completely safe. Just confirm to complete your swap.
</p>
<p className="text-xs text-green-300 leading-relaxed mt-2">
<span className="font-bold">🧪 Testnet Protection:</span>
This is a testnet - no real assets are at risk. However,
<span className="font-bold text-green-200"> ALWAYS use a testnet wallet</span>.
Never use your mainnet wallet address here.
</p>
</div>
</div>
)}This is a security explanation, not user-facing educational material. For smart contract audit details, consult the blockchain audit.