Introduction
On Ethereum, tokens are not understood by the protocol — they are balance entries in developer-deployed smart contracts. To let a dApp move tokens on your behalf, you must first call approve() to grant a spending allowance, then the dApp calls transferFrom() to execute the transfer. This two-step pattern is the root of an entire class of exploits that has drained hundreds of millions of dollars.
Radix takes a fundamentally different approach. Tokens are native resources — physical-like objects managed by the Radix Engine. There is no approval pattern because there is no need for one. Assets move directly between vaults, eliminating the attack surface entirely.
The Approval Problem
The ERC-20 approve() function grants a third-party contract permission to call transferFrom() and move tokens from your wallet. Most dApps request unlimited approvals (max uint256) for UX convenience — once granted, the approval persists forever unless manually revoked. This means every approved contract has permanent, unlimited access to that token in your wallet.
The pattern has a known frontrunning vulnerability documented since 2016: if a user changes an approval from amount X to amount Y, an attacker can frontrun by spending X before the new approval takes effect, then spend Y — stealing X + Y total. The increaseAllowance() function was introduced to mitigate this and later removed by OpenZeppelin due to its own security concerns.
Uniswap's Permit2 contract (November 2022) was designed to improve the approval experience but introduced new permit-signature phishing vectors. Within one month of launch, wallet drainers began exploiting permit signatures as an attack vector.
Exploit History
Approval-related exploits represent a significant share of DeFi losses:
| Incident | Amount | Date |
|---|---|---|
| Badger DAO (approval injection via frontend) | $120M | Dec 2021 |
| Wallet drainers (phishing + approval abuse) | $494M | 2024 |
| Wallet drainers (permit signatures) | $300M from 320k wallets | 2023 |
| ERC-20 phishing (single month, 89.5% ERC-20) | $71.5M | Mar 2024 |
| Largest single wallet drainer theft | $55.4M | 2024 |
The Badger DAO incident is especially instructive: the smart contracts functioned correctly. The attack exploited the gap between what users thought they were signing (a normal transaction) and what they actually signed (unlimited token approvals injected by compromised frontend code). On any chain with opaque transaction signing and the approval pattern, this attack vector exists permanently.
Radix's Resource Model
On Radix, tokens are native resources managed by the Radix Engine's finite state machine. The engine guarantees their physical-like behavior: resources are held in vaults, moved via buckets, and cannot be copied, double-spent, or accidentally destroyed.
Vaults and Buckets: Each vault accepts only one specific resource type (type safety enforced at the engine level). To send tokens, you withdraw them from a vault into a bucket and pass the bucket directly to the receiving component. The component receives the actual resource — not a permission to access it later.
No Approval Pattern: Because resources move directly, there is no approve() function and no spending allowance to exploit. The entire attack class — unlimited approvals, frontrunning approval changes, permit-signature phishing — does not exist on Radix.
Bucket Enforcement: The Radix Engine enforces that all buckets are empty at the end of every transaction. No resources can be lost, orphaned, or left in an intermediate state.
Why Reentrancy is Structurally Impossible
On Ethereum, reentrancy attacks occur when a contract calls an external contract, and the external contract calls back into the original before the first execution completes. This has enabled exploits from the 2016 DAO hack ($60M) to modern flash loan attacks.
Radix eliminates reentrancy through the Radix Engine's finite state machine model. State transitions are constrained so that callback-based reentrancy is not a valid state transition. Developers do not need to implement reentrancy guards, check-effects-interactions patterns, or mutex locks. The engine enforces correctness at the architecture level.
Implications for Autonomous Agents
For AI agents managing real value on-chain, the approval model creates an unacceptable attack surface. Every approval an agent grants is a permanent permission that can be exploited if any approved contract is compromised, upgraded maliciously, or exploited via a proxy pattern. Agents cannot intuit whether a contract is trustworthy — they can only verify formal properties.
Radix's native resource model gives agents exactly what they need: assets that move directly, transactions that are machine-readable, and an execution environment where entire categories of exploits are structurally impossible.
| Feature | ERC-20 (Ethereum) | Native Resources (Radix) |
|---|---|---|
| Token representation | Balance entry in a smart contract | Physical object in a vault |
| Transfer mechanism | Message to contract to update balances | Resource moves from vault → bucket → vault |
| Approval required? | Yes (approve + transferFrom) | No — direct resource transfer |
| Unlimited approvals | Common (persist forever) | Not applicable |
| Frontrunning risk | Yes (approval race condition) | Not applicable |
| Reentrancy | Possible (callback-based) | Structurally impossible (FSM) |
| Token loss | Possible (send to wrong address) | Prevented (bucket must empty, vault type-checks) |
| Wallet display | Opaque hex calldata | Human-readable manifest with named resources |
External Links
- What Are Native Assets? — Radix Knowledge Base
- What Are Vaults and Buckets? — Radix Knowledge Base
- Radix Engine v2: Asset-Oriented Smart Contracts — Radix Blog
- ERC-20 Approval Attack Vectors — Smart Contract Security Field Guide
- Explained: The BadgerDAO Hack — Halborn
- Asset-Oriented Architecture — Radix Docs
