Smart Contracts
Plain JavaScript, running in a deterministic sandbox, immutable by default, verifiable from source, talking to each other by async message-passing instead of synchronous calls.
TL;DR. Contracts on Aevum are plain JavaScript running in a deterministic sandbox, immutable by default, verifiable from source, and communicate through async message-passing — which makes reentrancy structurally impossible rather than merely discouraged.
Smart contracts on Aevum are plain JavaScript, running in a deterministic sandbox, immutable by default, verifiable from source, communicating with each other by async message-passing.
What's broken elsewhere
Four expensive problem classes drove this design:
- Reentrancy — the 2016 DAO hack (~$60M) and everything since it, made possible by synchronous calls that let a contract get re-invoked mid-execution
- Upgradeable contracts with hidden keys — users interact with code they audited, while developers hold a multisig that can swap it out from under them
- Unverified bytecode — what's actually on-chain is bytecode, divorced from source, and verifying the two match requires trusting a third party
- Monolithic contracts — large, feature-heavy contracts that are hard to audit, and a gas model that rewards building them that way anyway
Aevum's bet is that these are worth fixing structurally, at the protocol level, rather than patching with conventions and linters.
The four pillars
1. Async message-passing between contracts
Contracts can't synchronously call into each other mid-execution. Contract A sends a message to B and gets back a promise:
Inside a single contract, everything stays normal, synchronous JavaScript — functions, loops, conditionals, no changes there. Because a contract can never be interrupted mid-execution by another contract, reentrancy becomes structurally impossible, not just discouraged. Atomic multi-step operations are still supported, explicitly, through first-class transaction bundles:
2. Immutable by default
Deployed code is locked at deployment and can't change unless the author explicitly built in a proxy pattern with upgrade authority — and proxies are visibly labeled as such in explorers and wallets. For users, an audited contract stays audited: no silent code swap, no hidden rug pull switch. For developers, you can deploy something credibly permanent. Upgradeability has to be opted into and made visible, not assumed.
3. Verifiable by default
Contracts deploy as plain JavaScript source, not compiled bytecode. Verifying what's running is one hash comparison:
No compiler to trust, no third-party verification service in the loop. Explorers just show the source, with syntax highlighting and the author's own comments intact.
4. Economics that reward small, modular contracts
Three-layer pricing pushes toward composable design instead of monoliths:
- Deployment fee scales with source size — you pay for the storage up front
- Cold-load surcharge on the first call per block, proportional to code size — later calls in the same block are cheap
- Per-op gas for the actual execution work
A single 500KB monolith pays that cold-load surcharge every time it's first touched in a block. Five 100KB modules cost less in aggregate, because a transaction only cold-loads the contracts it actually touches.
How the pillars compose
Take a typical lending protocol. On Ethereum, something like this usually ships as a small handful of very large contracts — tens of thousands of lines, upgradeable behind a timelock multisig, source verification optional, reentrancy guards sprinkled in by hand. The audit runs hundreds of pages.
On Aevum, the same protocol naturally decomposes: a TokenVault holding deposits, an InterestRateOracle computing rates, a CollateralManager tracking health factors, a LiquidationEngine handling bad debt, and UserAccounts tracking per-user state. Each piece is small, independently deployable, independently auditable, immutable — and talks to the others asynchronously, where reentrancy between them isn't on the table.
That's just how engineering teams structure complex systems everywhere else: small pieces, clear interfaces. Ethereum's model makes that expensive and error-prone. Aevum's tries to make it the cheapest, safest, most natural way to build.
For developers
What stays the same
- Modern JavaScript — async/await, classes, closures, destructuring, BigInt, Map, Set
- Editor and type-checker support — TypeScript types strip at deploy time, plain JS runs on-chain
- Your existing package managers, linters, test runners, IDEs
- Synchronous code inside a single contract — helpers, loops, state updates, all normal JS
What's different, deliberately
- Cross-contract calls are async —
await E(otherContract).method(...) - No reentrancy guards to remember — the language structure prevents it
- Immutable by default — upgradeability is an explicit, visible opt-in
- Design leans modular — many small message-passing contracts instead of one big one
- Source is public by default — explorers show readable code, not bytecode
Recommended patterns
- One contract per concern — tokens, oracles, accounting, and access control each get their own small contract
- Pass capabilities explicitly between contracts instead of relying on global registries — it keeps the security model visible and auditable
- Use Zoe-style offer-safety patterns (borrowed from the Agoric ecosystem) when you need strict transactional semantics
- Reach for transaction bundles for multi-contract atomic operations — "borrow → swap → repay" as one all-or-nothing unit
Open questions
- Final per-op gas costs for SES operations — being tuned during the Phase 4 testnet
- Cold-load surcharge per byte — also being tuned against real testnet data
- The standard library available inside SES — which parts of the JS runtime API contracts can call
- A proper contract testing framework — a lightweight local in-memory chain for tests
- A canonical, audited proxy library for teams who do want upgradeability