Open a fresh revoke.cash scan on a three-year-old Ethereum address and you will almost always find the same ghost: an unlimited approval on USDC or WETH, granted to a router the user used exactly once in 2022, still sitting at 2^256 - 1 in the token contract's allowance mapping. The swap completed. The tab closed. The permission never did.
That is the real attack surface of DeFi from any wallet, Zelcore included. The private key stays safe. The seed stays offline. And funds still leave — because somewhere back in a signature prompt the user clicked through, they authorized a contract to move tokens on their behalf, and that authorization is a standing order the blockchain enforces until it is explicitly revoked.
This is the fourth and final article in the DeFi on Zelcore series. Parts 1 through 3 covered what Zelcore lets you do — one seed across 80+ chains, Fusion's cross-chain swap routing, fiat on-ramps, and native staking on Flux, ATOM, SOL, and ADA. This one covers how to do any of it without waking up drained. Zelcore defi security is operational security: reading signatures, pairing hardware, using multisig for anything that matters, and knowing where Zelcore's curated surface ends and WalletConnect territory begins.
The Approval Threat Model: Why DeFi Signatures Outlive the Trade
An ERC-20 approve(spender, amount) call does one thing: it writes a number to the token contract's allowance mapping under (owner, spender). That number does not decay. It does not expire. It sits there until the spender transfers against it or the owner explicitly overwrites it to zero.
Routers prefer unlimited approvals for a simple UX reason: they cost the user one extra transaction to grant, and then every future swap through that router skips the approve step. The amount encoded on-chain is type(uint256).max, which renders as thirty-two bytes of 0xff — permission to move every token of that type the wallet will ever hold. Uniswap Universal Router, 1inch, 0x, and Paraswap all default to this pattern.
The failure mode is dormant risk:
- The spender contract gets upgraded to something malicious (proxy pattern)
- The spender contract has a latent bug an attacker finds in 2027
- The approval was granted to a drainer clone masquerading as a legitimate router
Inferno Drainer, Pink Drainer, and the phishing-kit economy that followed them were not technical marvels. They were businesses built on the observation that users grant approvals faster than they revoke them.
Permit2, deployed by Uniswap Labs in November 2022 at the canonical address 0x000000000022D473030F116dDEE9F6B43aC78BA3, reshapes this. A user grants one allowance to the Permit2 contract, and then each individual transfer is authorized by an off-chain EIP-712 signature that carries its own expiry timestamp. Allowances become time-bounded, not perpetual.
EIP-2612 permit() goes further on compliant tokens: the approval itself is an off-chain signed message, submitted by the spender as part of the transaction. There is no separate approve transaction to see in the wallet. This is efficient and it is also why phishing sites love the flow — signing a permit is signing an approval, with none of the "I'm about to send a transaction" warning signals users learned to watch for. A quick refresher on wallets, gas, and approvals in DeFi covers the mechanics if this is the first time the distinction has mattered.
How Zelcore Surfaces the Signature: Read Before You Sign
When a dApp asks Zelcore to sign something through WalletConnect v2, the prompt surfaces four things you should verify before touching Confirm:
- Origin: the dApp URL. It should match the tab you initiated the action from. If you clicked a swap button on
app.uniswap.organd the prompt saysuniswap-airdrop-claim.xyz, stop. - Chain: the EVM network ID. A swap you think is on Arbitrum that arrives as mainnet is a hint something rewired the session.
- Method:
eth_sendTransaction,eth_signTypedData_v4,personal_sign, oreth_sign. Treateth_signTypedData_v4as the safer primitive — it renders structured fields. Treat bareeth_signon raw hashes as a red flag unless you absolutely trust the counterparty. - Payload: the actual call data or typed-data struct.
For on-chain approvals, the payload is a function call to the token contract. The to field is the token address. The data field begins with the four-byte selector 0x095ea7b3 for approve(address,uint256), followed by the spender address and the amount. If the amount field renders as ffffffff...ffff, that is unlimited — thirty-two bytes of maxed-out bits, permission in perpetuity.
EIP-712 prompts are easier to read: the domain separator shows the verifying contract, and the message fields for a Permit2 signature list token, spender, amount, and expiration in plain structure. The signature types and what each one lets an attacker do is worth the detour if you want a fuller map of which primitives cost you what when misused.
After any signature that grants a new allowance, audit it. revoke.cash covers 100+ EVM chains and surfaces both ERC-20 allowances and ERC-721 / ERC-1155 setApprovalForAll grants — the latter is the silent killer on NFT-enabled wallets, which is why the setApprovalForAll debt deserves its own monthly cleanup.
Hardware Wallet Pairing: Ledger and Trezor Through Zelcore
Hot keys are the default attack surface. Moving the signing key into dedicated hardware closes the entire category of malware that reads seed files or keystrokes.
Zelcore desktop pairs with Ledger Nano S Plus, Nano X, Stax, and Flex (the original Nano S hit end-of-life for new app installs in 2022 because its 320 KB flash could not hold modern apps) and with Trezor Model One, Model T, Safe 3, Safe 5, and Safe 7. The signing key stays inside the device's secure element or secure chip; Zelcore sends the unsigned transaction in, the device signs, and only the signature comes back out.
The non-negotiable operational rule: the device screen is the source of truth. Not the desktop UI. Every transaction has to be reviewed on the hardware display and confirmed with the physical buttons before the signature is released. If the desktop shows "Swap 1 ETH for USDC" and the device shows approve(0xBad..., 2^256-1), the device is correct.
This creates a specific failure mode called blind signing. When the device cannot parse what it is being asked to approve — an opaque 32-byte hash, calldata for a contract it has no ABI for — it can only display the raw payload. Ledger's Ethereum app ships with blind signing disabled by default. The user has to go into the app settings and toggle Blind signing: Enabled before it will sign opaque DeFi calldata. Trezor Suite throws an "Unknown contract" warning for the same reason.
The fix is clear signing. Ledger's ERC-7730 descriptor standard lets dApps publish JSON files that register human-readable field names for their contracts. With ERC-7730 in place, a Uniswap swap renders tokenIn, amountOutMin, and recipient directly on the hardware screen instead of a hash. Enabling blind signing should be a deliberate, per-session decision, not a permanent setting — the full reasoning on blind signing on hardware wallets applies here without modification.
Pairing hardware with Zelcore removes the hot-key risk. It does not remove the blind-sign risk. Both mitigations are necessary.
SSP Multisig for DeFi Treasuries: BIP48 on UTXO, ERC-4337 on EVM
For holdings that survive a single lost laptop or a single phished session, one signer is not enough. SSP — Secure Self-custody Platform, at sspwallet.io — is Zelcore's 2-of-2 multisig companion. One key lives in the SSP browser extension, the other in the SSP Key mobile app. Every spend requires both.
On UTXO chains, SSP uses native script-level multisig via BIP48 derivation paths (m/48'/coin_type'/account'/script_type'). Bitcoin, Litecoin, Flux, Dogecoin, and 30-plus other UTXO chains in Zelcore's registry enforce the 2-of-2 at the chain level. No smart contract is involved; the consensus rules do the work.
On EVM chains, SSP uses ERC-4337 account abstraction. User operations flow through the canonical EntryPoint contract — v0.6 deployed in March 2023 at 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789, v0.7 deployed in 2024. The SSP smart account validates the 2-of-2 signature policy inside the contract itself.
For a DeFi treasury, SSP on EVM means every approve(), every swap, every bridge deposit requires a second device to co-sign the exact same UserOperation hash. A phished desktop session cannot move funds alone. A compromised phone cannot either. Both have to confirm the same payload.
ERC-4337 also brings two DeFi-shaped upgrades:
- Paymasters: gas can be sponsored or paid in the token being swapped, so cold-storage ETH is not required to move stablecoins
- Batching: approve, swap, and unapprove can be packaged into a single atomic UserOperation. Unlimited allowances never sit idle between calls because the call that grants them and the call that rescinds them are the same transaction
Anything above a personal stack — DAO treasury, team runway, long-term accumulation — belongs in SSP rather than a single-signer hot wallet.
Custom RPC Endpoints: Censorship Resistance and MEV Defence
The RPC endpoint is the mouth of the wallet. It broadcasts transactions and reads state. Default public RPCs are convenient; they are also the narrow pipe where censorship and MEV extraction happen.
After the August 8, 2022 OFAC sanctioning of Tornado Cash, major commercial RPC providers began applying transaction-level filtering that rejects calls touching sanctioned addresses. Whether or not a user agrees with the policy, the reality is that a default RPC is a policy layer between the wallet and the chain — and a policy layer can drop lawful transactions for reasons that have nothing to do with their legality in the user's jurisdiction.
Zelcore lets users override the RPC per EVM chain and point at Infura, Alchemy, Ankr, QuickNode, PublicNode, or a self-hosted Geth / Nethermind / Reth / Erigon node. The setting is per-chain and persists across sessions.
Two categories of RPC upgrade are worth the setup time:
- Uncensored endpoints or a self-run node preserve the ability to broadcast and read what public providers may refuse
- MEV-protecting RPCs — Flashbots Protect at
rpc.flashbots.net, MEV Blocker atrpc.mevblocker.io, bloXroute Protect — route transactions through private orderflow so sandwich bots and frontrunners never see them in the public mempool. On any DEX trade above a few hundred dollars, this is the difference between getting the quoted price and getting the price after a searcher has extracted a few bps in between
UTXO chains follow the same pattern: Zelcore supports custom Blockbook backends, which let privacy-conscious users avoid broadcasting their xpub and full address set to a third-party indexer. The full walkthrough on using custom RPC endpoints in Zelcore has the per-chain setup.
What Zelcore Does NOT Do Natively — and When WalletConnect Takes Over
A wallet that does everything is a wallet with a large attack surface. Zelcore ships a deliberately narrow native scope:
- No in-wallet on-chain DEX aggregator. Fusion is cross-chain instant-swap aggregation across centralized providers (ChangeNOW, SimpleSwap, Godex, StealthEX), covered in Part 2. It is not a Uniswap-style or 1inch-style or Jupiter-style on-chain router. On-chain DEX trading happens through WalletConnect to the DEX's own frontend
- No native bridging. Moving USDC from Ethereum to Arbitrum, or WBTC from BNB Chain to Base, goes through Across, Stargate, Hop, or a chain-native bridge via WalletConnect. Zelcore signs the approval and deposit; the routing lives in the bridge dApp
- No NFT marketplace execution. OpenSea, Blur, Magic Eden — all WalletConnect-mediated. The Seaport
setApprovalForAllconduit request surfaces as an ordinary signature prompt the user has to read - No mobile dApp browser. Zelcore mobile does not ship an in-app web3 browser by default; mobile DeFi is desktop-anchored via WalletConnect QR pairing or deep link. Fewer in-app browser zero-days reach the signing key
The trade-off is intentional. Less third-party code in the core binary means fewer paths from a dApp bug to the signing key. It also means users cross a clear line when they open a WalletConnect session — a session they can audit, name, and revoke from Zelcore's session list the moment they are done with it.
Series Capstone: Four Parts, One Posture
The four parts of this series map to four decisions a self-custody DeFi user actually makes:
- Part 1 picked the entry point: one 24-word seed across 80+ chains, WalletConnect v2 as the dApp bridge, Zelcore versus MetaMask, Phantom, and Keplr
- Part 2 picked the swap surface: when Fusion's four-provider cross-chain routing with fixed or floating rates is the right tool, when an on-chain DEX through WalletConnect is, and how MoonPay and Guardarian on-ramps feed the stack
- Part 3 picked the yield strategy: native delegated staking on Flux, ATOM, SOL, and ADA through Zelcore Earn, validator selection, and the honest reason Zelcore does not ship LSTs or lending products
- Part 4 — this one — picked the security posture: read every EIP-712 field, sign on-device, audit approvals monthly at revoke.cash, use SSP for anything above a personal stack, point mainnet RPC at a protected endpoint, and know which actions leave the native surface for WalletConnect
None of the four is sufficient alone. A perfect entry point with unlimited approvals bleeds. A perfect swap routing with a compromised hot key drains in one signature. Perfect staking with a public RPC on a frontrun-heavy L1 costs more than it earns. The defensible posture is all four at once — and that is what it takes to turn "using Zelcore for DeFi" from a convenience into a discipline.



