Asentum

Concepts

The Smart Contract Model

Canonical reference · Estimated read time: 14 minutes

TL;DR

Smart contracts on Asentum are plain JavaScript running in a deterministic sandbox, immutable by default, verifiable from source, communicating via async message-passing, and economically rewarded for being small and modular. Together these four design choices create a contract experience that is meaningfully safer than Ethereum's while also being friendlier to JavaScript developers than any existing blockchain.

What's broken on Ethereum (and why this matters)

Smart contract platforms have spent a decade learning hard lessons, mostly by losing billions of dollars to exploits. The four most expensive classes of problem are:

  1. Reentrancy. The DAO hack in 2016 (~$60M at the time) and a long tail of smaller exploits ever since. Caused by the synchronous-call model allowing a contract to be re-invoked mid-execution.
  2. Upgradeable contracts with hidden upgrade keys. Users think they're interacting with audited code, but a multisig the developer controls can swap in new code at any time. Many "audited" DeFi contracts have this escape hatch.
  3. Unverified bytecode. Bytecode on-chain, source code elsewhere. Users have to trust a third party (usually Etherscan) that the source matches the bytecode. Sometimes it doesn't.
  4. Complex monolithic contracts. Big contracts with many features are hard to audit, hard to understand, and tend to have more bugs per line. Ethereum's gas model makes monoliths slightly cheaper to call than equivalent modular designs, which incentivizes the wrong pattern.

Asentum is designed to remove all four of these classes of problem — not just mitigate them with patterns and discipline, but remove them structurally at the protocol level.

The four pillars

1. Async message-passing between contracts

Contract A cannot synchronously invoke contract B and wait for a return value mid-execution. Instead, A sends a message to B and receives a promise for the result.

async function transfer(tokenRef, to, amount) {
  const result = await E(tokenRef).transfer(to, amount);
  if (!result) throw new Error('transfer failed');
}

Within a single contract, code is normal synchronous JavaScript — function calls, loops, conditionals, helpers. The async model only applies to calls between separate contracts.

Reentrancy is structurally impossible. When a contract sends a message to another contract, it can't be interrupted and re-entered mid-execution. The DAO hack cannot happen here. Oracle reentrancy attacks cannot happen here. Entire categories of smart contract bugs simply do not exist as a possibility.

Atomic operations are still supported via first-class transaction bundles. A single transaction can encode multiple contract calls that execute as an atomic unit, rolling back all state if any of them fails:

const bundle = tx.bundle([
  E(aave).borrow(usdc, 10_000n),
  E(uniswap).swap(usdc, eth, 10_000n),
  E(compound).repay(eth),
]);
// Atomic: all succeed, or the entire bundle reverts.

2. Immutable by default

A deployed contract's code is locked in at deploy time and cannot be changed, ever, unless the author explicitly built in a proxy pattern with a configurable upgrade authority. When they do, the proxy is visibly and clearly labeled as such in block explorers and wallet interfaces.

What this means for users: when you audit a contract, you know what you're getting. Nobody can silently swap in new code tomorrow. No "trust the multisig" story. No hidden rug-pull capability.

What this means for developers: you can deploy contracts that are credibly uncensorable and unchangeable. When you do need upgradeability, you use an explicit proxy pattern, which forces centralization to be visible to users rather than hidden from them.

3. Verifiable by default

Contracts are deployed as plain JavaScript source, not compiled bytecode. Verification reduces to a single hash comparison:

hash(submitted_source) == deployed_code_hash

There is no compiler to trust, no "Etherscan verified" third-party dependency, no fragile compilation-reproduction dance. The source on-chain is the source; anyone can see it, read it, audit it, and verify that the deployed code matches any claimed source by hashing the file locally.

Block explorers show contract source directly, with syntax highlighting, comments, everything the author wrote.

4. Economic rewards for small, modular contracts

Asentum's contract pricing has three layers, and together they create economic pressure toward small, composable, single-purpose contracts:

  • Deployment fee scales with source size. You pay upfront for the storage burden your contract places on the chain.
  • Cold-load surcharge on first call per block. The first call to a given contract within a block pays a surcharge proportional to the contract's code size — capturing the real cost of loading the contract into the VM. Subsequent calls within the same block are cheap.
  • Per-op gas covers the actual execution cost of work done.

Why this rewards modularity: a monolithic 500 KB contract is expensive to cold-load every time. A system of five 100 KB modular contracts is cheaper because transactions only cold-load the ones they actually touch. Popular library contracts get cold-loaded once per block and warm-called cheaply by everyone else.

How the four pillars compose

Each pillar is valuable individually, but the combination is where the real story lives. Consider a typical DeFi protocol — say, a lending market.

On Ethereum, a typical lending protocol (Aave, Compound) is deployed as a small handful of large contracts totaling tens of thousands of lines. The contracts are upgradeable via a timelock multisig. Source verification is opt-in after deployment. Reentrancy guards are sprinkled throughout the code. Audit reports run hundreds of pages.

On Asentum, the same protocol would naturally decompose into smaller pieces:

  • A TokenVault contract that holds deposited assets
  • An InterestRateOracle contract that computes rates
  • A CollateralManager contract that tracks health factors
  • A LiquidationEngine contract that handles undercollateralized positions
  • A UserAccounts contract that tracks per-user state

Each piece is small — maybe a few hundred lines. Each piece is independently deployable, independently auditable, independently immutable. They communicate via async messages; no reentrancy is possible between them.

This isn't a theoretical improvement. It's how real engineering organizations structure complex systems everywhere else: small composable pieces with clear interfaces. Ethereum makes that structure expensive and error-prone. Asentum makes it the cheapest, safest, and most natural choice.

For developers

What stays the same

  • You write JavaScript. Normal modern JS — async/await, classes, closures, destructuring, BigInt, Map, Set, everything you already know.
  • Your editor and type-checker still work. TypeScript types can be stripped at deploy time, leaving the runtime JS on-chain.
  • You use tools you know. Package managers, linters, test runners, IDEs.
  • Within a single contract, code is synchronous. Helper functions, loops, state updates — all normal JS.

What's different (in good ways)

  • Cross-contract calls are async. Use await E(otherContract).method(...).
  • No reentrancy guards. You don't need them. The language doesn't permit reentrancy.
  • Contracts are immutable by default. If you need upgradeability, you explicitly use a proxy pattern.
  • Design for modularity. Split functionality into small contracts that send messages to each other.
  • Source is public. Every deployed contract is readable in the block explorer as source code, not bytecode.

Open questions

Things that need more definition before mainnet:

  • Per-op gas costs for SES operations — tuning TBD during Phase 4 testnet.
  • Cold-load surcharge per byte — tuning TBD.
  • Standard library for contracts — which parts of the JS runtime API are available inside SES?
  • Contract testing framework — we'll ship a lightweight test runner that can run contracts against a local in-memory chain.
  • Recommended proxy pattern library — we should publish a canonical, audited proxy implementation so developers who want upgradeability don't roll their own.

Read next