Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,65 @@
Sovereign Bridge SCs
# Sovereign Bridge Smart Contracts

Contracts that deploy and run a validator-signed bridge between MultiversX and a Sovereign chain. The focus below is on how the on-chain pieces collaborate; shared helper crates sit alongside these contracts but are not described here.

## Contract Roles

- `sovereign-forge/`: entry point for sovereign creators; walks through a four-phase deployment to mint a new chain ID and request contract instances from a Chain Factory.
- `chain-factory/`: factory that clones the contract templates for each sovereign (Chain Config, Header Verifier, MultiversX ESDT Safe, Fee Market) and wires ownership to the correct controller.
- `chain-config/`: stores the sovereign’s configuration and validator set (BLS keys). Handles validator registration during the genesis phase and later updates triggered from signed bridge operations.
- `header-verifier/`: keeps the current validator set and verifies BLS-aggregated signatures for bundles of bridge operations (`hashOfHashes`). It gates execution by marking operation hashes as registered/locked/executed.
- `mvx-esdt-safe/`: MultiversX-side vault. Accepts deposits destined for the sovereign chain (burns or escrows tokens based on the chosen mechanism), emits bridge events, and executes incoming signed operations to mint/unlock tokens or perform contract calls.
- `mvx-fee-market/`: manages bridge fees and whitelists on the MultiversX side. Fee changes and whitelist updates are themselves bridge operations that must be signed and registered by the Header Verifier.
- `sov-esdt-safe/`: sovereign-side vault. Burns incoming tokens, emits the events that validators sign, and exposes admin endpoints for updating its configuration and fee sink address.
- `sov-fee-market/`: sovereign-side fee configuration; owners can set/remove fees, distribute balances, and maintain a fee whitelist.
- `interactor/`: chain-simulator flows for end-to-end tests; see `interactor/HowToRun.md`.
- `testing-sc/`: scenario test contract and fixtures.

## How the Pieces Interact

- **Bootstrapping a sovereign:** A creator calls `sovereign-forge` in four phases. The forge asks a `chain-factory` (per shard) to deploy Chain Config, MultiversX ESDT Safe, Fee Market, then Header Verifier. When everything is live, `chain-factory::completeSetupPhase` finalizes the Chain Config setup, then transfers ownership of the MultiversX-side contracts to the Header Verifier so all bridge operations are signature-gated.
- **Validator set lifecycle:** During the genesis phase, validators register BLS keys in `chain-config`. The Header Verifier pulls this set on `completeSetupPhase`. Future rotations happen through `header-verifier::changeValidatorSet`, which requires a signed operation hash from the previous epoch and the list of new validator key IDs stored in Chain Config.
- **Sovereign → MultiversX transfers:** Users deposit into `sov-esdt-safe`, which burns the tokens and emits a deposit event. Sovereign validators batch those events into a list of operations, sign the resulting `hashOfHashes`, and the Sovereign Bridge Service calls `header-verifier::registerBridgeOps` on MultiversX. Each operation is executed through `mvx-esdt-safe::executeBridgeOps`, which locks the operation hash in the Header Verifier, mints/unlocks the needed tokens (or performs a contract call), and then signals completion so the hash is cleared.
- **MultiversX → Sovereign transfers:** Users call `mvx-esdt-safe::deposit`. The contract enforces whitelists/blacklists and fee collection, then either burns wrapped tokens or escrows native ones before emitting a deposit event. Sovereign validators observe these events and mint/unlock the corresponding assets on the sovereign chain according to their local logic.
- **Token mechanics:** `mvx-esdt-safe` supports two modes per token: burn (requires local mint/burn roles and the token to be trusted) or lock (escrow on MultiversX, unlock on return). Registering new sovereign-minted tokens on MultiversX (`registerToken`) issues a new ESDT with the sovereign prefix and maps it to the sovereign identifier; `registerNativeToken` bootstraps the sovereign chain’s own native asset.
- **Fee handling:** Deposits can require an upfront fee payment that is forwarded to `mvx-fee-market::subtractFee`. The MultiversX fee market also exposes bridge-controlled operations to set/remove fees, distribute balances, and manage a whitelist; these paths are guarded by the Header Verifier just like token transfers.
- **Pause and safeguards:** Both safes can be paused; setup phases must be completed before normal bridge operations proceed; hash locking in the Header Verifier prevents duplicate execution and enforces operation nonces.

## System Diagram

```
Sovereign Creator
|
v deploy phases
sovereign-forge -> chain-factory ----------------------+
| | |
| +--> chain-config (validators) |
| +--> mvx-esdt-safe (vault) |
| +--> mvx-fee-market (fees) |
| +--> header-verifier (owner) <--+
|
Sovereign Chain MultiversX
------------------ -------------------
sov-esdt-safe (burn & emit) ----> Validators sign ----> header-verifier
| |
sov-fee-market (fees) <---- fee lookups ----- mvx-esdt-safe -- mvx-fee-market
|
executeBridgeOps <-----+
(mint/unlock/SC calls)
```

> For more details about the Cross-Chain Execution, please take a look at the [official documentation](https://docs.multiversx.com/sovereign/cross-chain-execution).

## Development

- Build all contracts: `sc-meta all build`
- Run contract tests from the repo root or within a contract crate: `sc-meta test`
- Simulator E2E flows: follow `interactor/HowToRun.md` (start `sc-meta cs`, delete stale `state.toml`, run the `always_deploy_setup_first` test to seed state, then execute specific tests).

## Repository Map

- `sovereign-forge/`, `chain-factory/`: deployment orchestration
- `chain-config/`, `header-verifier/`: validator management and signature verification
- `mvx-esdt-safe/`, `mvx-fee-market/`: MultiversX bridge vault and fee logic
- `sov-esdt-safe/`, `sov-fee-market/`: sovereign-side vault and fee logic
- `interactor/`, `testing-sc/`: integration and scenario tests
9 changes: 9 additions & 0 deletions chain-config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Chain Config Contract

Maintains the validator set and sovereign chain configuration. Genesis registration happens here before the bridge is opened, and later updates come through signed bridge operations.

- **Initialization:** `init` accepts an optional `SovereignConfig` (min/max validators, stakes, limits). Defaults are applied if none is provided.
- **Validator lifecycle:** Validators register/unregister during the setup phase via `register` / `unregister`. After setup, updates flow through bridge-controlled endpoints `registerBlsKey` and `unregisterBlsKey` (operation hashes are locked through the Header Verifier).
- **Configuration updates:** Owners can adjust the sovereign config during setup with `updateSovereignConfigSetupPhase`; after setup the signed path `updateSovereignConfig` is used.
- **Completing setup:** `completeSetupPhase` finalizes genesis once the minimum validator count is present. The Header Verifier then mirrors the validator set for signature checks.
- **Interactions:** The Header Verifier reads the BLS key map stored here to verify bridge operations. Sovereign Forge deploys this contract first, and Chain Factory clones it from a template when spinning up a new sovereign.
13 changes: 13 additions & 0 deletions chain-factory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Chain Factory Contract

Factory that clones the sovereign contract templates on MultiversX and wires ownership to the correct controllers.

- **Initialization:** `init` receives the Sovereign Forge address plus template addresses for Chain Config, Header Verifier, MultiversX ESDT Safe, and Fee Market. Templates are required to be valid smart contract addresses.
- **Deploying per sovereign:** Only admins (typically the Sovereign Forge) may call:
- `deploySovereignChainConfigContract(opt_config)`
- `deployEsdtSafe(sovereign_owner, sov_prefix, opt_config)`
- `deployFeeMarket(esdt_safe_address, fee)`
- `deployHeaderVerifier(sovereign_contracts)`
Each returns the fresh contract address.
- **Completing setup:** `completeSetupPhase` calls `completeSetupPhase` on Chain Config, then transfers ownership of Chain Config, MultiversX ESDT Safe, and Fee Market to the Header Verifier, and finally completes their setup phases. This makes the Header Verifier the gatekeeper for bridge operations.
- **Interactions:** Sovereign Forge drives deployments through this factory. After phase four, the factory’s setup completion hooks finish wiring the sovereign’s contract suite.
9 changes: 9 additions & 0 deletions header-verifier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Header Verifier Contract

Holds the active validator set and verifies BLS-aggregated signatures for bridge operation bundles (`hashOfHashes`). It locks operation hashes to prevent double execution and signals completion back to the calling contracts.

- **Setup:** `completeSetupPhase` fetches the genesis validator set from Chain Config and marks setup done. Only proceeds once Chain Config completed its own setup.
- **Registering operations:** `registerBridgeOps(signature, hashOfHashes, bitmap, epoch, operations)` checks setup, validates the signature against the current epoch’s validator keys, ensures the bundle hash matches, and marks each operation hash as `NotLocked`.
- **Validator rotation:** `changeValidatorSet` uses the previous epoch’s signatures to register a new validator key set (by IDs stored in Chain Config). Older epochs are pruned as `MAX_STORED_EPOCHS` is exceeded.
- **Execution locking:** `lockOperationHash(hashOfHashes, opHash, nonce)` marks an operation as `Locked` (enforcing the expected nonce). `removeExecutedHash` clears the status after completion; calling contracts typically use the wrapper in `complete_operation`.
- **Callers:** The contract expects to be the owner of MultiversX ESDT Safe and Fee Market so it can authorize bridge operations. Sovereign Forge arranges this via Chain Factory during setup.
10 changes: 10 additions & 0 deletions mvx-esdt-safe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# MultiversX ESDT Safe

MultiversX-side vault for the bridge. It accepts deposits heading to the sovereign chain, executes signed operations coming from the sovereign side, and manages token registration plus burn/lock mechanics.

- **Initialization:** `init(sovereign_owner, sovereign_forge_address, sov_token_prefix, opt_config)` sets the sovereign owner/admin, validates the sovereign token prefix, stores config (whitelist/blacklist, gas limits, max amounts), and starts paused.
- **Deposits (MultiversX → Sovereign):** `deposit(to, optTransferData)` enforces pause/blacklists/whitelists, charges bridge fees via the Fee Market, then burns or locks tokens based on the configured mechanism before emitting a deposit event.
- **Execution (Sovereign → MultiversX):** `executeBridgeOps(hashOfHashes, operation)` is called after validators register the operation in the Header Verifier. It locks the operation hash, mints/unlocks tokens (or performs a contract call), and emits completion. Refunds are handled if execution fails.
- **Token management:** `registerToken` issues a wrapped ESDT for a sovereign token ID (requires fee payment). `registerNativeToken` issues the sovereign chain’s native token during setup. Burn/lock mechanism can be toggled via `setTokenBurnMechanism*` and `setTokenLockMechanism*`.
- **Configuration & safety:** Config updates (`updateEsdtSafeConfig*`), pause control (`pauseContract`), and fee market address are gated by setup checks. `completeSetupPhase` unpauses, ensures native token and fee market are set, and hands off control to the Header Verifier.
- **Interactions:** Owned by the Header Verifier after setup. Calls the Fee Market to subtract fees and the Header Verifier to lock/clear operation hashes.
9 changes: 9 additions & 0 deletions mvx-fee-market/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# MultiversX Fee Market

Manages bridge fees and whitelists on the MultiversX side. After setup, fee changes must be authorized through the Header Verifier.

- **Initialization:** `init(esdt_safe_address, fee)` stores the linked ESDT Safe and optional initial fee schedule.
- **Setup phase paths (owner-only):** `setFeeDuringSetupPhase`, `removeFeeDuringSetupPhase`, `addUsersToWhitelistSetupPhase`, `removeUsersFromWhitelistSetupPhase` allow configuring fees and whitelists before the bridge is opened.
- **Bridge-controlled paths:** `setFee`, `removeFee`, `distributeFees`, `addUsersToWhitelist`, `removeUsersFromWhitelist` are executed via signed operations. Each locks the operation hash in the Header Verifier before applying the change.
- **Completion:** `completeSetupPhase` marks the contract ready for bridge-controlled changes.
- **Interactions:** The ESDT Safe calls `subtractFee` (from shared endpoints) during deposits. The Header Verifier owns this contract after setup to gate operations.
9 changes: 9 additions & 0 deletions sov-esdt-safe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Sovereign ESDT Safe

Sovereign-side vault. It burns incoming assets to emit bridge events, lets admins adjust configuration, and anchors fee collection to the sovereign fee market.

- **Initialization:** `init(fee_market_address, opt_config)` stores the linked fee market, applies config defaults if omitted, and starts paused.
- **Deposits (Sovereign → MultiversX):** `deposit(to, optTransferData)` burns the provided tokens and emits a deposit event containing the transfer data for validators to sign.
- **Registering assets:** `registerToken` issues a sovereign-wrapped token ID (requires the standard issue cost in EGLD). Tokens must carry the sovereign prefix. The call burns the payment and emits a registration event.
- **Configuration:** `updateConfiguration` updates the ESDT Safe config (whitelist/blacklist, gas limits, caps). `setFeeMarketAddress` retargets the fee sink.
- **Interactions:** The Fee Market on the sovereign side is the fee controller. Events emitted here are batched and signed by validators; matching operations are later executed on MultiversX by the Header Verifier + MultiversX ESDT Safe.
7 changes: 7 additions & 0 deletions sov-fee-market/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Sovereign Fee Market

Simple fee controller on the sovereign chain. Owners configure fees, distribute balances, and maintain a whitelist.

- **Initialization:** `init(esdt_safe_address, fee)` links the sovereign ESDT Safe and optionally seeds an initial fee.
- **Operations (owner-only):** `setFee`, `removeFee`, `distributeFees`, `addUsersToWhitelist`, `removeUsersFromWhitelist`.
- **Interactions:** The sovereign ESDT Safe references this contract for fee lookups when processing deposits destined for MultiversX.
13 changes: 13 additions & 0 deletions sovereign-forge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Sovereign Forge

Orchestrates the four-phase deployment of a sovereign’s MultiversX-side contracts via Chain Factory and tracks chain IDs per creator.

- **Initialization:** `init(opt_deploy_cost)` sets the required EGLD deposit for deployments and pauses the contract.
- **Registering factory/trusted tokens:** `registerChainFactory(shard_id, address)` wires a Chain Factory per shard. `registerTrustedToken` stores token IDs allowed for burn/lock mechanics downstream.
- **Deployment phases (caller = sovereign creator):**
- `deployPhaseOne(opt_preferred_chain_id, config)` → deploy Chain Config and reserve a chain ID.
- `deployPhaseTwo(opt_config)` → deploy MultiversX ESDT Safe with the reserved prefix.
- `deployPhaseThree(fee)` → deploy MultiversX Fee Market linked to the ESDT Safe.
- `deployPhaseFour()` → deploy Header Verifier with references to the other contracts.
- **Finishing setup:** `completeSetupPhase` triggers Chain Factory to run the per-contract `completeSetupPhase` calls and transfer ownership to the Header Verifier. Marks the sovereign as setup-complete.
- **Interactions:** Drives Chain Factory to clone templates. Validators and the Header Verifier rely on the chain ID generated here to namespace token IDs and contract lookups.
Loading