AsseteraECS
AsseteraECS (Execution, Clearing and Settlement): the escrow-based, UUPS-upgradeable, gasless, compliance-gated order and offer book behind Assetera trading.
AsseteraECS (Execution, Clearing and Settlement) is the Solidity contract that settles secondary trading on Assetera. It holds an order book and a targeted-offer book, escrows the tokens users trade, and gates every state change behind an off-chain compliance attestation. It is the on-chain record of what was traded, by whom, and under which terms.
A first acquisition settles somewhere else
A buyer's first acquisition of an asset goes through a different contract, with its own address, its own roles and its own EIP-712 domain. See Primary issuance.
What it is
| Property | What it means for you |
|---|---|
| Escrow-based, with no on-chain matching engine | Makers post priced limit orders and the contract escrows the sell side at once. A taker executes against a specific order id, and nothing on chain scans the book for crosses. Every execution is an explicit call against an order the caller chose, which is why the lifecycle pages describe transitions rather than a matching algorithm. |
| UUPS-upgradeable (ERC-1967) | Logic lives in an implementation behind a single proxy. Always index and interact with the proxy address. Confirm the live implementation via the eip1967.proxy.implementation storage slot. |
| Gasless (ERC-2771 meta-tx) | Users pay no gas and hold no native tokens. Calls are relayed through a trusted Forwarder; the contract resolves the real actor with _msgSender(). Read identity from the address in each event (maker, taker, account, by, proposedBy), never from tx.from. See Events. |
| Compliance-gated | Every state-changing call carries a single-use, deadline-bound EIP-712 KYC attestation signed off-chain. Fee terms travel in a separate fee attestation. See Attestations. |
| Source available | The Solidity source, tests and audit scope are public: Assetera-AG/AsseteraEvmContracts. Read the contract itself in contracts/src/AsseteraECS.sol and the review boundary in AUDIT-SCOPE.md. Links are pinned to the evm-contracts-v8.1.0 tag so they cannot rot. |
Formerly AsseteraExchange
The rename is cosmetic. Deployed addresses, the ABI, event and function selectors, and the storage layout are all unchanged, so no redeploy or migration is involved. One identifier deliberately keeps the old spelling, the EIP-712 domain name. See Attestations.
Roles
The contract uses OpenZeppelin AccessControl. The roles an integrator should know about:
| Role | Purpose |
|---|---|
DEFAULT_ADMIN_ROLE | Governance: upgrades, pause/unpause, compliance toggles, fee-collector allowlist, and the emergency cancelOrderForUser / cancelOfferForUser exits. Held by a Safe multisig in production. |
KYC_OPERATOR_ROLE | The operator key whose EIP-712 signature authorizes each KYC-gated action. |
FEE_OPERATOR_ROLE | The operator key whose EIP-712 signature sets the fee terms snapshotted onto an order or offer. |
Fee terms are authorized by a separate FeeAttestation signed by FEE_OPERATOR_ROLE, not the KYC
attestation. See Attestations.
Where it runs
AsseteraECS is deployed on four networks: Ethereum and Polygon (mainnets), and Sepolia and Polygon Amoy (their testnets). Pick a network for its contract addresses:
Addresses exactly as published in @asseteragmbh/evm-contracts, the version these docs are built against.
Chain ID 1 · CAIP-2 eip155:1 · deployed at block 25,795,740
| Contract | Address (integrate against this) |
|---|---|
| AsseteraECS | 0xf045d3FE81C14d8c13DbaB0b03a4Ea1505e499ad |
| AsseteraPrimarySales | 0xF62757dd232DC7582A5d46F62aAcDb6B739223Dc |
| Forwarder | 0x2244B33a97f91284D53d0A12d42F237927C3DBf7 |
Behind the proxy. The addresses above are the stable ones. The UUPS implementation below is what the proxy currently delegates to. It is useful for verifying the deployed bytecode, but it changes on every upgrade, so never hardcode it.
| Contract | Implementation (changes on every upgrade) |
|---|---|
| AsseteraECS | 0xF2f8Dfd9bbc1AD2A78447A0196deC84e3397737B |
| AsseteraPrimarySales | 0xB6De6C29f039ed53e993f916961A758D32C13c11 |
Chain ID 137 · CAIP-2 eip155:137 · deployed at block 92,344,157
| Contract | Address (integrate against this) |
|---|---|
| AsseteraECS | 0xf045d3FE81C14d8c13DbaB0b03a4Ea1505e499ad |
| AsseteraPrimarySales | 0xF62757dd232DC7582A5d46F62aAcDb6B739223Dc |
| Forwarder | 0x2244B33a97f91284D53d0A12d42F237927C3DBf7 |
Behind the proxy. The addresses above are the stable ones. The UUPS implementation below is what the proxy currently delegates to. It is useful for verifying the deployed bytecode, but it changes on every upgrade, so never hardcode it.
| Contract | Implementation (changes on every upgrade) |
|---|---|
| AsseteraECS | 0xB6De6C29f039ed53e993f916961A758D32C13c11 |
| AsseteraPrimarySales | 0xCb0ef38528fd695116B745722d7d03485584175F |
Chain ID 80002 · CAIP-2 eip155:80002 · deployed at block 45,229,125
| Contract | Address (integrate against this) |
|---|---|
| AsseteraECS | 0xf045d3FE81C14d8c13DbaB0b03a4Ea1505e499ad |
| AsseteraPrimarySales | 0xF62757dd232DC7582A5d46F62aAcDb6B739223Dc |
| Forwarder | 0x2244B33a97f91284D53d0A12d42F237927C3DBf7 |
| MockRWA | 0xECe9f75Eb6af58B7c70773BbC5922E49fD65F3E0 |
| MockUSDC | 0x85D7B2569b3d69320F05A4FFB140Ca4521989A15 |
Behind the proxy. The addresses above are the stable ones. The UUPS implementation below is what the proxy currently delegates to. It is useful for verifying the deployed bytecode, but it changes on every upgrade, so never hardcode it.
| Contract | Implementation (changes on every upgrade) |
|---|---|
| AsseteraECS | 0xB6De6C29f039ed53e993f916961A758D32C13c11 |
| AsseteraPrimarySales | 0xC0c7F32806a8C99287151B7F4886Ef2CDEFf2C7d |
Chain ID 11155111 · CAIP-2 eip155:11155111 · deployed at block 11,514,803
| Contract | Address (integrate against this) |
|---|---|
| AsseteraECS | 0xf045d3FE81C14d8c13DbaB0b03a4Ea1505e499ad |
| AsseteraPrimarySales | 0xF62757dd232DC7582A5d46F62aAcDb6B739223Dc |
| Forwarder | 0x2244B33a97f91284D53d0A12d42F237927C3DBf7 |
| MockRWA | 0xECe9f75Eb6af58B7c70773BbC5922E49fD65F3E0 |
| MockUSDC | 0x85D7B2569b3d69320F05A4FFB140Ca4521989A15 |
Behind the proxy. The addresses above are the stable ones. The UUPS implementation below is what the proxy currently delegates to. It is useful for verifying the deployed bytecode, but it changes on every upgrade, so never hardcode it.
| Contract | Implementation (changes on every upgrade) |
|---|---|
| AsseteraECS | 0xB6De6C29f039ed53e993f916961A758D32C13c11 |
| AsseteraPrimarySales | 0xC0c7F32806a8C99287151B7F4886Ef2CDEFf2C7d |
The ABI and every address above are published with each deployment in the TypeScript SDK; resolve them from the package rather than hardcoding.
The same address on every chain, and why that is safe to rely on
AsseteraECS, AsseteraPrimarySales and the Forwarder each carry the same proxy address on all four chains, because they are deployed with CREATE3. The implementation behind each proxy differs per chain, which is what the second table on each tab shows.
Address your calls to the proxy, and read the live implementation from the
eip1967.proxy.implementation storage slot rather than from a document. Resolve even the proxy from
the SDK: a chain with no deployment record returns undefined, which is the correct way to learn
that a contract is not available there.
Where to go next
Order lifecycle
place → fill → settle, plus cancel and expiry, and what each step escrows.
Offer lifecycle
The regulator-mandated targeted offer / counter-offer negotiation flow.
Primary issuance
The other side of the estate: how a buyer's first acquisition settles, through AsseteraPrimarySales.
Security reviews
Nethermind Security reviewed the primary settlement router and reported no issues. The report is public.
Events
The event catalog you index against, with the meta-tx actor model.
Attestations
The EIP-712 KYC and fee attestation model that authorizes each action.
Source on GitHub
The public AsseteraEvmContracts repo: Solidity source, Foundry tests, functional spec and audit scope.
Read the source
The contract repository is public. These deep links are pinned to the evm-contracts-v8.1.0 tag.
| File | What it covers |
|---|---|
contracts/src/AsseteraECS.sol | The assembled contract: UUPS, ERC-2771 and the initializer, over the OrderBook / OfferBook modules. |
contracts/AUDIT-SCOPE.md | The combined review boundary, and the entry point to the two below. |
contracts/AUDIT-SCOPE-SECONDARY.md | This contract's own scope: the order book and the offer book. |
contracts/AUDIT-SCOPE-PRIMARY.md | The settlement router's scope. A separate proxy, reviewable on its own. |
contracts/docs/FUNCTIONAL_SPEC.md | The behavioural specification the lifecycle pages summarize. |
contracts/docs/INDEXER_EVENT_SCHEMA.md | The event schema of record: canonical signatures, topic0 hashes, error selectors. |
Real-time updates (SSE)
Use a server-minted, channel-scoped ticket to receive Server-Sent Events without exposing an Assetera API token to the browser.
TypeScript SDK
Consume AsseteraECS with @asseteragmbh/evm-contracts: ABIs, per-chain addresses, a viem client, and wagmi hooks, all generated from the contract.