Unique Characteristics of Radix
Throughout the course of this audit, we have noticed that Radix has many differences in relation to most other blockchains. Two aspects of Radix that we would like to note (and what makes Radix stand out from the rest of the blockchains) are as follows:
The resource and badge system
The security-through-ownership system
We briefly cover why these are innovative and novel and also discuss the security benefits of designing systems in this way.
Resource and badge system
Resources are to Radix what tokens are to Ethereum. The biggest difference is that resources are natively built into the Radix engine, as opposed to tokens, which are not native and must be implemented as smart contracts.
Why is this important? Having resources be a part of the engine itself allows the engine to maintain invariants as well as impose rules and restrictions regarding how resources are managed and used. In essence, this provides more control than a typical smart contract would have, and the control lies entirely with the blockchain developers themselves.
In Radix, there are two types of resources: fungible and nonfungible. When a new resource is created, it creates a new component out of a preexisting native blueprint. The native blueprint can be thought of as a smart contract from Ethereum, except that it is maintained by the Radix development team and can access the engine in ways that user-defined blueprints cannot (through an API that only they have access to). This in turn means that users do not have to write their own code for their own resources, which then reduces the attack surface, as new attack surfaces cannot be introduced due to users writing erroneous code.
Additionally, one of the most unique aspects of Radix is how the resource system ties into how access-control mechanisms are set up. In Radix, if you want to restrict access to certain functions or methods in blueprints or restrict access to certain resources, it is as easy as checking to see if the caller holds a certain nonfungible resource. In this context, the nonfungible resource would be called a "badge", and this badge is what allows callers to prove that they have the required permissions to perform some action.
Therefore, in order to set up access control, it is as simple as creating a new nonfungible resource and minting it out to necessary parties. It is a very clean and simple system, and it is incredibly difficult to introduce access-control issues through user error.
Another key point is that access control in Radix is the default. A good example of this is the native accounts blueprint. In Radix, every account is a component created from the native accounts blueprint, and so the actual logic within each account is restricted to what the native accounts blueprint implements. This ensures that any security measures (such as not allowing users access to accounts that they are not authorized to access) are implemented at a blockchain level. This makes it absolutely impossible for any implementation level issues to arise out of user error.
In contrast, to implement smart accounts on Ethereum, not only do user-defined smart contracts need to be used (see ERC-4337 for example), but off-chain entities must also be used to submit transactions on behalf of these smart accounts. Additionally, since smart contracts do not automatically contain access-control logic, all access-control must be implemented manually by the developers of the smart account system.
The complex nature of such implementations introduce bugs such as this one↗ or this one↗. It also makes the bugs very difficult to fix at times, as the fixes may need to be deployed to every smart account (although there are some modular designs which prevents the need to do this). In contrast, on Radix, a single blockchain upgrade is enough to fix any bug.
Having said that, the native accounts blueprint contains such simple logic, that we were not able to find any vulnerabilities in it during the audit. It is a testament to the phrase "simple is good".
Security-through-ownership system
While Radix has many sophisticated features like native resources, badges, and access-control systems, its fundamental security model is effectively simple, built on two key rules:
No dangling resources — they must either be persisted through ownership or destroyed.
Only the creator of a resource has the power to destroy it.
These two rules provide a strong security guarantee for the developers building on Radix with little mental overhead.
The power of this approach is evident when comparing implementations of common DeFi patterns. Consider flash loans: on Ethereum, they typically require complex reentrant call patterns where the lender calls into borrower code, which calls back to repay, with careful balance checking needed throughout. This complexity creates many opportunities for subtle bugs.
On Radix, the same functionality is achieved through simple ownership rules:
The lender creates two buckets: borrowed funds and a "promise" NFT that only the lender can burn.
The borrower receives both through a
.borrow()
call.To complete the loan, the borrower must call
.return()
with both repayment funds and the promise NFT.The lender verifies the repayment amount and burns the promise NFT.
If the borrower fails to return the funds, the transaction will abort as the promise is left dangling.
This functionality is often a complex choreography of reentrant calls, but in Radix it is a straightforward exchange of resources, with clear intent and security guaranteed by the ownership rules themselves.
This pattern can be found throughout Radix at every level of implementation. Even core features like resource management rely on these ownership rules rather than complex invariants being checked. When depositing resources, the system simply drop()
s the transient instance (bucket) and then increments the vault's balance. If an attacker tries to deposit a bucket holding a different kind of resource, the operation will abort as they (resource A) are not the creator (of bucket of resource B). Simple rules create strong security.