Skip to main content

EBSI ↔ Ethereum Bridge

DEUSS bonds are issued and settled natively on EBSI, the EU's regulated enterprise ledger, which is where the platform's system of record for ownership lives. Investor liquidity, secondary trading venues and custodial infrastructure, however, are concentrated on the Ethereum ecosystem. The Bridge closes that gap: it lets a DEUSS bond token minted on EBSI be represented, held and traded on an Ethereum-compatible chain as a wrapped, 1:1-backed mirror token. The Bridge is designed so that the same asset never exists as two independently spendable copies.

The Bridge is built on the Secure Asset Transfer Protocol (SATP), an open, standardised interoperability protocol for atomic cross-ledger asset transfer, implemented through Hyperledger Cacti's SATP-Hermes gateway. DEUSS does not reimplement the transfer protocol itself — it adapts SATP's gateway and wrapper-contract model to the DEUSS bond token, and operates one gateway per chain.

:::warning Pilot status The Bridge is currently a pilot running between a EBSI-pilot network and the Ethereum Sepolia testnet. The design guarantees described on this page (1:1 backing, conservation of supply, role-gated custody) are its target properties. They are not yet fully enforced by the current implementation. Several security, governance and operational aspects must be completed before the Bridge can be used with real assets. They are listed under Known Limitations & Future Work. :::


Why a Bridge​

Keeping issuance and settlement of DEUSS bonds on EBSI is a regulatory and business requirement, not an incidental choice: EBSI provides the compliance guarantees the product is built around. But confining the token to EBSI would also confine it to EBSI's investor base and tooling.

The Bridge resolves this without compromising either side:

  • EBSI stays the source of truth. The original DEUSSToken position is never duplicated. It is locked into a pooled bridge custody on EBSI while the corresponding wrapped balance exists on Ethereum.
  • Ethereum gets a fungible mirror. The wrapped token (WDEUSS) carries no independent supply of its own. Once every transfer session has completed, each WDEUSS unit in circulation corresponds to one DEUSS unit held in bridge custody on EBSI.
  • The transfer is reversible. Value can be moved to Ethereum and back to EBSI, and the protocol is designed to conserve the asset's supply end to end on both legs. In the pilot, transfers are started by the bridge operator on the holder's behalf.

How It Works​

Each chain runs its own wrapper contract, which the gateway calls into to move value. On EBSI, the wrapper talks to a SATPTokenAdapter — a dedicated custody actuator placed in front of the existing DEUSSToken, so bridging support could be added without modifying the bond token contract itself. On Ethereum, there is no separate adapter: the wrapper mints and burns WDEUSSToken balances directly, since that token exists solely as the bridge's own mirror.

Transfer Flow — EBSI to Ethereum​

In both diagrams, tokenId is the ERC-6909 bond token ID. By convention it is the same on both chains. assetId is a fresh identifier that each gateway generates for its own side of every SATP session, so the two wrappers hold different assetIds for the same transfer. In stage 0 each gateway registers ("wraps") the asset under its assetId in its wrapper contract, together with the asset's owner (the holder on the source side, whom lock pulls from; the recipient on the destination side) and the ontology that maps the wrapper's calls to token functions.

The permission check during wrap only works on EBSI. The Ethereum-side wrapper, taken unchanged from upstream Cacti, does not read the result of hasBridgeRole. If its BRIDGE_ROLE on WDEUSSToken were missing, wrap and lock would still succeed, and the session would fail only in stage 3, when WDEUSSToken rejects the mint or burn.

The transfer request is a call to the gateway's transact API, in which the caller describes both sides of the transfer. On the EBSI side, the request names the SATPTokenAdapter, not DEUSSToken, as the asset's token contract. In the pilot, the bridge operator makes this call on the holder's behalf. The API must be reachable only from a restricted network (see Known Limitations & Future Work). An approval given to the adapter or the Ethereum wrapper is a standing authorization, so holders should approve exactly the amount of the transfer they are about to start. Granting the adapter operator status with setOperator authorizes it for the holder's entire balance and should not be used for bridging. The gateway's own approve-address endpoint always returns the wrapper address. On Ethereum that is correct, but on EBSI the approval must go to the adapter, so that endpoint must not be used for EBSI transfers.

Transfer Flow — Ethereum back to EBSI​

The return trip runs the same protocol in reverse. The holder approves the Ethereum-side wrapper on WDEUSSToken, the wrapper pulls the WDEUSS amount into its own balance and burns it, and only then does the EBSI-side wrapper assign the corresponding amount out of adapter custody to the recipient. No new DEUSS is minted on EBSI: the "mint" step only verifies that the adapter's custody covers the amount. unlock exists only to roll back a lock when a transfer fails.

Recovery of failed sessions. SATP-Hermes rolls back failed sessions automatically only when crash recovery is enabled, and it is currently disabled in both gateway configurations. Until then, the operator has to finish or reverse a failed session manually as wrapper owner. The operator uses each wrapper's own assetId for the session and always calls the variants that take the tokenId explicitly: unlock, mint and burn as (assetId, amount, tokenId), and assign as (assetId, recipient, amount, tokenId). What to do depends on the stage at which the session stopped:

  • After lock, before the destination mint: unlock on the source wrapper returns the locked amount to the holder.
  • After the destination mint, before the source burn: burn on the destination wrapper, then unlock on the source wrapper. On Ethereum this destroys the WDEUSS minted into the wrapper. On EBSI nothing was minted, and the Ethereum-side unlock works without the EBSI burn. The burn should still be called, so that the open amount recorded by the EBSI mint cannot later be assigned out of custody.
  • After the source burn, before assign: the value is already committed. Calling assign on the destination wrapper delivers it to the recipient.

Recovery steps that move DEUSS are ordinary DEUSSToken transfers, so the compliance rules below apply to them as well and can block them.

DEUSS compliance rules apply to the bridge. Every bridge movement of DEUSS is an ordinary DEUSSToken operation, so the platform's entity registry and token controls apply:

  • The holder's approve of the adapter must pass the registry's approval check.
  • Each transferFrom must pass the registry's transfer check. The holder, the adapter and, on the return trip, the recipient must therefore all be enabled in the registry.
  • Only the holder's free (non-frozen) balance can be locked.
  • With a paused token ID, or a globally paused DEUSSToken, a bridge transfer cannot complete in either direction.

On the return trip (Ethereum → EBSI), DEUSS moves only at the final assign, after the WDEUSS has already been burned. A pause, a recipient not enabled in the registry, or a frozen adapter balance therefore does not stop the session early. The session stops in the "after the source burn" recovery state until the block is lifted. The operator should check these conditions before starting a return transfer.

In both directions the commit follows the SATP order: the destination side mints first, the source side burns second, and the destination side assigns last. The recipient receives value only through assign, after the source-side burn. On Ethereum the freshly minted WDEUSS waits in the wrapper until then. On EBSI the "mint" moves nothing, and assign releases the value from custody. In a correctly executed session, the same value therefore never exists as a spendable EBSI balance and a spendable Ethereum balance at the same time.


Core Business Capabilities​

1. Lock-and-Mint / Burn-and-Release Custody Model​

Value moving to Ethereum is locked into the EBSI-side adapter's custody and mints an equal WDEUSS amount; value moving back burns that WDEUSS amount and releases the matching custody balance. By design, total WDEUSS supply therefore mirrors what the EBSI adapter currently holds. The two chains do not check each other on-chain. The invariant is meant to be maintained by the gateways executing SATP (see Known Limitations & Future Work), and anyone can audit it by comparing WDEUSSToken.totalSupply(tokenId) on Ethereum with the adapter's DEUSSToken balance on EBSI. The adapter's internal custody ledger has no public getter, so its DEUSSToken balance is the observable figure. The custody history can also be reconstructed from the adapter's Locked, Unlocked and Released events. The two figures legitimately differ while sessions are in flight or stuck, or if DEUSS reaches or leaves the adapter outside the bridge, for example by a direct transfer or by a privileged DEUSS action such as a forced transfer or burn. A freeze on the adapter does not change the figure, but it blocks releases from custody.

2. Defense-in-Depth Custody Accounting​

The SATPTokenAdapter keeps its own custody ledger, separate from the wrapper contract's bookkeeping. unlock and assign must pass both the wrapper's and the adapter's own custody check, so a bug in the wrapper's bookkeeping cannot release more than the adapter has recorded as locked. The limit is the whole pooled custody of a token ID across all holders, not one holder's position. It does not protect against misuse of the wrapper's or the adapter's owner key (see Known Limitations & Future Work).

3. Governed, Role-Gated Bridging​

Every custody-moving function (lock, unlock, assign on the EBSI adapter, mint/burn on WDEUSSToken) is gated behind an on-chain BRIDGE_ROLE, which the deployment process grants only to the deployed wrapper contract. The wrapper itself accepts calls only from its owner. The gateway must sign its on-chain transactions with that owner account. Every movement is therefore an on-chain, auditable call from one known account. Which transfers that account executes is decided by the requests the gateway receives.

4. Ontology-Driven Integration​

Each chain's wrapper is configured through a declarative ontology — a JSON document mapping the abstract SATP interactions (lock, unlock, mint, burn, assign, checkPermission) to the exact function signatures and arguments of the token contracts on that chain. This keeps the SATP protocol logic unchanged (the only local change to Cacti is a small big-integer type and conversion fix, described under Operations) while allowing the concrete contracts underneath — today DEUSSToken/SATPTokenAdapter on EBSI and WDEUSSToken on Ethereum — to be adapted or extended to additional asset types in the future without protocol-level changes.

5. Upgradeable Deployment​

All bridge contracts are deployed via CREATE2 through dedicated deployer contracts. The deployer contracts themselves are created afresh on every run, so contract addresses are not reproducible between deployments or environments. The EBSI-side adapter and wrapper sit behind owner-controlled upgradeable beacon proxies, and WDEUSSToken is a UUPS proxy upgradeable only by its owner. These can be upgraded without changing the addresses that the gateways and integrations are configured against. The Ethereum-side wrapper is the unmodified upstream SATP contract, deployed without a proxy, so changing it means redeploying and reconfiguring the Ethereum gateway.


Technical Components​

ComponentChainRole
DEUSSTokenEBSIThe existing native ERC-6909 bond token; unmodified by the bridge
SATPTokenAdapterEBSICustody actuator: pulls/releases real DEUSSToken balances on the wrapper's behalf, with its own independent custody ledger
SATPWrapperContract (EBSI side)EBSISATP-facing contract the gateway calls into; resolves abstract interactions to adapter calls via the token's ontology
SATPWrapperContract (Ethereum side)EthereumSame protocol role on the destination chain; calls WDEUSSToken directly, no adapter needed
WDEUSSTokenEthereumWrapped, ERC-6909-based mirror token with no independent supply — minted/burned only by holders of BRIDGE_ROLE, granted to the bridge wrapper
SATP-Hermes Gateway (×2, one per chain)Off-chainHyperledger Cacti component that executes the SATP protocol session and drives the on-chain wrapper calls
Ontology files (native-chain / dst-chain)Off-chain configDeclarative mapping from SATP interactions to each chain's actual contract functions

Security & Governance​

  • Owner-only wrappers and role-gated tokens. Every wrapper operation is restricted to the wrapper's owner, and every custody-moving token function to BRIDGE_ROLE. With the current deployment scripts, the deployer account of each chain owns that chain's adapter, WDEUSSToken and upgrade authority. On EBSI the deployment scripts also make the deployer the wrapper's owner, so as deployed, the EBSI gateway signs with the deployer key. On Ethereum the wrapper's owner is the configured bridge address (SATP_BRIDGE_ADDRESS), which defaults to the deployer and is not set in the pipeline. These keys must be protected like issuer keys. Separating them is listed under Known Limitations & Future Work.
  • Two separate gateway keys. Each gateway has an on-chain signer account, which submits the wrapper transactions. It also has a separate identity keypair that only signs SATP protocol messages and holds no on-chain power.
  • Independent custody bookkeeping on the EBSI adapter, isolated from the wrapper's own state, described above under Core Capabilities.
  • Re-runnable deployment. Deployment scripts skip any contract whose address is already configured in the pipeline variables and has code. An explicit override (FORCE_DEPLOY) deploys fresh contracts. The old contracts then keep their custody and roles. Each deployment is recorded in JSON manifests, and the role-grant step reads its target addresses from them.
  • Role-granting is a separate step from deployment (GrantSATPBridgeRole / GrantWDEUSSBridgeRole). The grants run as their own pipeline jobs immediately after deploy, so the moment a wrapper contract becomes authorized to move funds is a distinct, logged action. It is not a separate approval gate.

Operations & Delivery Pipeline​

The Bridge is delivered through a dedicated GitLab CI/CD pipeline covering both legs end to end:

  • Every pipeline (including merge requests) builds, tests and lints the contracts.
  • Deploy, role-granting and verification run only on manually started pipelines and release tags.
  • The CI image and the gateway image are rebuilt when their inputs change (the CI Dockerfile, or the pinned Cacti submodule). They are also rebuilt whenever GitLab cannot compute a diff: manually started, scheduled, tag, API-triggered and new-branch pipelines. A change to the local Cacti patches alone does not trigger a gateway image rebuild. Both images are built in the first pipeline stage, so a failed image build blocks the rest of the pipeline. The gateways are started from the published gateway image separately.
  • Registry setup. Before the first transfer, the SATPTokenAdapter must be enabled in the DEUSS entity registry, because every approval to it and every custody transfer is checked there. This is a manual step and is not part of the bridge deployment pipeline.
  • Contracts (chain/) are a self-contained Foundry project, built, tested and deployed independently for the EBSI-style network and for Ethereum, with an optional pipeline-level "force deploy" override for controlled redeployment.
  • Gateways (bridge/gateway/satp/) run as one container per chain. Starting them through the provided make up, make restart or make refresh targets always re-renders their configuration from .env first, so an edited .env is not left behind a stale config. A plain docker compose up or an automatic container restart reuses the last rendered configuration. SATP-Hermes crash recovery is currently disabled in both gateway configurations.
  • Hyperledger Cacti is consumed as a pinned upstream submodule. A local patch is maintained and applied automatically during the CI gateway image build (a local build requires applying it manually) so that large token identifiers are represented as big integers rather than plain JavaScript numbers. This is necessary because DEUSS bond token IDs are full 256-bit hashes of ISIN and version, far beyond the range a plain JavaScript number can represent exactly. Transfer amounts are still handled as JavaScript numbers by the gateway, and amounts above 2^53−1 units are rejected. DEUSSToken defines no decimals, so this limit is far above any realistic bond amount.

Current Scope & Roadmap​

  • The Bridge is piloted between a EBSI pilot network and the Ethereum Sepolia testnet. Deployment onto the actual EBSI pilot network follows a separate, dedicated deployment procedure; the Ethereum/Sepolia leg is unaffected by that distinction.
  • Only the DEUSS bond token (ERC-6909) is wired end to end today. The ontology-driven design means additional token types or standards can be bridged later without changes to the underlying SATP protocol layer.
  • Transfers are currently triggered directly against the gateway's transfer API. Surfacing bridge transfers as a first-class action in the DEUSS application layer is a natural next step once the underlying protocol has seen further operational validation.

Known Limitations & Future Work​

The pilot implementation has the following known gaps. They must be addressed before the Bridge is used with real assets:

  • Cross-chain consistency of transfer requests. The gateways do not yet verify that the source and destination sides of a transfer request match (amount, token ID and token contract). Until they do, the 1:1 backing depends entirely on who can submit transfer requests. The gateways must enforce this consistency, and the stage-0 permission check on Ethereum must be enforced as it is on EBSI.
  • Access to the gateway API. The SATP-Hermes API currently runs without authentication and without TLS, and the provided compose file publishes the gateway ports on all host interfaces. It must be protected by authentication and network restrictions, and holders need a controlled way to start their own transfers, ideally from the DEUSS application layer.
  • Key and ownership separation. Each chain's deployer account currently owns that chain's bridge contracts and their upgrade authority. The gateway must sign with the wrapper owner account. On EBSI the deployment scripts always make the deployer the wrapper owner; the configurable bridge address is stored but not used for access control there. Giving the EBSI gateway its own key currently requires a manual ownership transfer of the wrapper after deployment. The adapter owner can also re-point the adapter to a different token. Contract ownership and upgrade authority should move to a separate admin or multisig account that the gateways do not hold.
  • Protection of bridge custody on EBSI. Bridged DEUSS sits in the adapter's balance, where privileged DEUSS roles (forced transfer, burn, freeze) can still act on it. DEUSSToken already supports marking an address as protected custody. The adapter should be registered as protected. Protection is permanent and also blocks burns from the adapter, so it has to be designed together with the bond lifecycle handling below.
  • Automatic recovery. Crash recovery and automatic rollback are disabled, so failed sessions are resolved manually. They should be enabled and tested, and the manual procedure should be formalized for the remaining cases.
  • Bond lifecycle for bridged positions. On EBSI, the adapter is the recorded holder of all bridged DEUSS. How coupons, redemption and other lifecycle events reach WDEUSS holders is not yet defined.
  • Deployment robustness. Skipping already-deployed contracts depends on manually maintained pipeline variables, so an automatically retried first deployment can create duplicate contracts. Role grants run without a separate approval gate. Deployment should read state from the manifests, which first requires storing them persistently (today they are CI artifacts that expire after 14 days), and production deployments should be gated.
  • Image supply chain. CI publishes the CI image and the gateway image under a mutable latest tag from any branch. The gateways pull latest when started, and the deploy and role-grant jobs, which receive the deployer keys, run in the latest CI image. Both should use pinned images built only from reviewed code.
  • Audit tooling. The adapter's custody ledger has no public getter. A getter and a monitoring job that continuously compares WDEUSS supply with EBSI custody should be added.