Back to Home

Account

0xad1d193c4e1c...af29f8b5394b
ByzantiumSource VerifiedEdit this contract
Deployed June 12, 2018 (8 years ago)Block 5,776,463

Disposable execution account from a 2018 fleet: a delegatecall proxy with a hand packed calldata entry point that lets its controller call or delegatecall anything through it.

Byzantium EraVerified Source

Historical Significance

This is what an execution account looked like when gas was the binding constraint and the caller was a program rather than a person. Nothing about the calldata layout is ABI encoded, because ABI encoding would have meant paying for padding on every call. The address sits at offset 8 rather than offset 4 for one reason: it puts the twenty bytes exactly where a single memory word can be masked to reach them.

The design also separates two powers that later account abstraction work would keep separate on purpose. Slot 1 gives the account a standing implementation that anyone can reach through the fallback. proxy() gives a short list of privileged callers the ability to route a one off call or delegatecall through the account without changing that implementation. Deploying many of them in a single transaction, all under one controller, is the 2018 answer to a question smart accounts are still answering.

Token Information
Decimals
0
Key Facts
Deployment Block
5,776,463
Deployment Date
Jun 12, 2018, 02:48 PM
Code Size
453.0 B

Description

Two storage slots and two entry points. Slot 0 holds an owner, slot 1 holds an optional implementation, and everything else is inline assembly.

The fallback is a proxy. If slot 1 is set, the whole calldata is delegatecalled into it and the return data is passed straight back, so the account can be given behaviour after deployment without redeploying. If slot 1 is empty the fallback accepts plain ether and does nothing else.

The named entry point is proxy(), and it reads none of its arguments the way Solidity would. Callers pack them by hand: one flags byte at offset 7, a twenty byte target at offset 8, and the payload from offset 28 onward, which is why the function declares no parameters and the body starts by copying calldata into memory at 0x18 so that a single mload lands on the address. The low nibble of the flags byte selects call or delegatecall, the high nibble selects whether return data is forwarded or discarded, and anything else reverts. Three callers are allowed through: the owner in slot 0, and two addresses written into the code at compile time.

One of those two hardcoded addresses is the account's own deployer, which created these in batches within single transactions. The owner slot points at a separate controller contract whose interface reads createAccounts, importAccounts, getAccounts, accounts and getAccountCount, alongside its own proxy() and a withdraw(). That controller is where the name comes from: to the system that built them, these are accounts, not proxies.

Source Verified

Solidityeh_crack_source_verified
Compiler: v0.4.24

Bytecode Overview

Opcodes453
Unique Opcodes114
Jump Instructions27
Storage Operations5

External Links

Related contracts