Introduction
The Network of Momentum Multi-chain Infrastructure is an interoperability solution dedicated for the development of a sustainable, thriving ecosystem. Users are able to frictionlessly swap NoM assets between different blockchain networks through a seamless procedure enabled by user-friendly interfaces. This integration with the wider blockchain ecosystem will simultaneously attract more users (builders, developers, marketers, liquidity providers, etc.) and will also unlock a core component of the Network of Momentum: the Protocol Level Liquidity.
This documentation is intended to provide users and developers all the necessary information to interact, develop and maintain the Network of Momentum Multi-chain Infrastructure:
- The Decentralized Bridge to wrap and unwrap native NoM assets
- The Protocol Level Liquidity that enables the Orbital Program
Both components are covered in the Zenon Improvement Proposal ZIP:sumamu-0001
. The complete ZIP can be found here.
Field | Description |
---|---|
zip | ZIP:sumamu-0001 |
title | NoM Multichain infrastructure |
author | @sumamu @sumoshi |
status | Draft |
type | Hard fork |
acceptance | upon usage by the community |
activation | upon usage by the community |
created | 2023-03-07 |
license | GPL v3.0 |
link | https://forum.zenon.org/t/zip-sumamu-0001-final/1327 |
Architecture Overview
The whole design architecture of the decentralized cross-chain infrastructure is focused around security considerations.
The possibility to exchange and swap assets in a trustless, decentralized way between NoM and other networks is conditioned by the existence of a decentralized bridge solution.
The liquidity embedded in its current form does not have the means to distribute rewards to liquidity providers in a trustless and automated way.
Not a single centralized entity except the end user is able to move funds and several security mechanisms are organized in a layered structure to prevent and deter malicious actors from exploiting the infrastructure. The TSS participants are only able to sign transactions; they do not have the possibility to move user funds.
There are three distinct components that will enable a multi-chain vision with Orbital Program at its core:
- The Core Contracts
- The Protocol Level Liquidity
- The Orchestrator Layer
The Orchestrator Layer will enable the relay and data transmissions between networks and will orchestrate the TSS signing ceremonies.
The Core Contracts will verify resulting signatures and interpret incoming events accordingly.
The Protocol Level Liquidity is a stand alone embedded contract that distributes the corresponding fraction of the dual-coin emission to eligible Liquidity Providers.
- On-chain
- Core Contracts
- Protocol Level Liquidity
- Off-chain
- Orchestrator Layer: Orchestrator nodes based on Pillar nodes that form their own peer-to-peer network. Orchestrator nodes observe the Core Contract on each supported network and produce events that the Core Contracts validate. The orchestrator node will try to sign a confirmed event that was witnessed in the next TSS ceremony. The signing will succeed if there is a super-majority (
>66%
).
- Orchestrator Layer: Orchestrator nodes based on Pillar nodes that form their own peer-to-peer network. Orchestrator nodes observe the Core Contract on each supported network and produce events that the Core Contracts validate. The orchestrator node will try to sign a confirmed event that was witnessed in the next TSS ceremony. The signing will succeed if there is a super-majority (
Unlike other bridge architectures, there is no additional peer-to-peer communication needed to confirm the event: each orchestrator node witness and processes all the events locally (after a finality threshold) and a successful TSS signing ceremony represents the off-chain consensus on which events are valid wraps and unwraps.
Modus Operandi
The decentralized bridge is based on lock-and-release
/ mint-and-burn
mechanisms: native assets are locked
/ burned
on one side and released
/minted
on the other side.
This particular interoperability solution allows easy transfers from NoM to other networks. The embedded bridge contract allows the control of native ZTS assets on NoM, while EVM Solidity contracts allow the control of wrapped ZTS assets on EVM compatible chains.
Depending on the direction of the swap, the following scenarios may appear:
-
Example native
ZNN/wZNN
(nativeZNN
andwZNN
asERC-20
token): NativeZNN
is locked in the bridge embedded contract on NoM and its wrapped representation,wZNN
is minted by the Ethereum contract. For the opposite direction,wZNN
is burned by the Ethereum smart contract and nativeZNN
is released by the embedded bridge. -
Example stablecoin
DAI/zDAI
(DAI
asERC-20
token andzDAI
asZTS
token):
DAI
stablecoin is locked in the Ethereum smart contract, while the bridge embedded contract mints the equivalent amount on NoM. For the opposite direction, zDAI
is burned by the embedded contract and ERC-20
DAI
is released by the Ethereum smart contract.
Compatibility
A robust interoperability solution must also maximize the compatibility with other distributed ledgers. Currently only NoM and EVM networks are supported. Other networks are based on different models and will be supported in the future.
Account model compatibility
EVM compatibility
The initial phase will consist of an implementation specifically designed for EVM compatibility (Ethereum, BNB Smart Chain, etc.):
- Execution compatibility:
Ethereum virtual machine
(i.e.Solidity
) - Cryptographic compatibility:
ECDSA
signatures (i.e.secp256k1
) - API compatibility:
ETH JSON-RPC
(i.e. EthereumJSON-RPC API
)
This interoperability solution will unlock liquidity from a wide range of both Layer-1
and Layer-2
EVM
compatible networks such as Ethereum, BNB Smart Chain, Polygon, Avalanche, Arbitrum, etc.
Liquidity pools will be gradually deployed on those networks for the wrapped representations of ZTS
assets, enabling a seamless process for users to access and get onboarded into the NoM ecosystem.
Non-EVM compatibility
In the future, more non-EVM networks can be connected by implementing custom integrations (Polkadot, Cosmos, etc.):
- Execution compatibility: Virtual machine type (i.e.
WASM
) - Cryptographic compatibility:
EdDSA
signatures (i.e.Ed25519
) - API compatibility: custom
API
for each network
UTXO model compatibility
In the next phase, compatibility with UTXO networks (Bitcoin, Litecoin, etc.), in particular Bitcoin, is expected to be implemented and rolled-out. Further design changes are necessary for optimal integration with existent BIP340
, BIP341
(e.g. Schnorr signatures
- Musig2
, MAST
, Tapscript
, etc.).
Confirmations to Finality
Different networks use different consensus protocols with different finality assumptions. In the table below one can find the number confirmations needed for a transaction to become final.
Orchestrator nodes proceed with the TSS signing ceremony only for finalized cross-chain transactions.
Network Name | Network Class | Chain identifier | Finality |
---|---|---|---|
Network of Momentum | 1 | 1 | 6 momentums |
Ethereum | 2 | 1 | 1 epoch ~ 6.4 minutes |
Binance Smart Chain | 2 | 56 | 33 seconds (6 secs after fast finality) |
Bitcoin | 3 | 1 | 6 blocks ~ 60 minutes |
Participants
Network of Momentum Multi-chain Infrastructure has four different type of participants: Guardians
, Orchestrator Nodes
, Liquidity Providers
and the Administration Module
.
Guardians
Guardians will be elected from prominent members of the community. Their main responsibility is to safeguard the infrastructure in case of an emergency. They will act as judges in case of a major failure of the infrastructure and they are responsible to appoint a new admin.
Administration Module
The role of the administration module is to manage the infrastructure. It cannot move funds and its permissions are limited in scope. The Core Contracts are designed to be managed by the community members through a governance module, similar to Accelerator-Z. At the moment the governance capabilities of NoM are insufficient to ensure this functionality. Until a solution is developed, the admin will be managed by the maintainers of the codebase.
Orchestrator Nodes
All the nodes of the orchestrator layer will run on Pillars. This design decision is based on the consideration that the security of the whole network depends on NoM consensus running nodes. Pillar operators already have both the technical background and know-how to operate nodes and a sufficient stake in the network to responsibly manage this critical piece of infrastructure. Pillars will be able to be part of the orchestrator peer-to-peer layer (libp2p
) and participate in the threshold signature (TSS
) ceremonies.
Liquidity Provides
Liquidity Provides (LPs
) are users with available capital that are incentivized through the Orbital Program to directly participate into the network by staking their liquidity in order to receive dual-coin (ZNN
and QSR
) rewards. They must ensure adequate levels of liquidity for users to be able to frictionlessly swap their assets in and out of the ecosystem.
Orbital Program
Orbital Program is a protocol level liquidity program that incentivizes liquidity providers to participate and pool together liquidity for the wrapped representations of ZNN
, QSR
and ZTS
tokens in exchange for the aforementioned fraction of the dual-coin emission. This program will create a sustainable model for external liquidity providers to participate into the network.
Without proper incentives, LPs may lack interest to join the Orbital Program and this in turn will hurt the ecosystem by limiting the potential of external users that would swap their assets to NoM. Moreover, beyond Orbital Program, new untapped markets and gateways to access NoM are necessary for a healthy development of the ecosystem.
What is the liquidity embedded contract?
The liquidity embedded contract is the initial placeholder that accumulates dual-coin rewards for the upcoming Orbital Program. The liquidity contract was upgraded to enable the Orbital Program and is based on the staking embedded contract.
How to participate in the Orbital Program?
A liquidity provider that wants to participate in the Orbital Program must supply a liquidity pool with the corresponding assets, swap the resulting LP token to NoM and lock it up into the liquidity embedded in order to be eligible for dual-coin rewards.
For example, several Ethereum users wants to become a liquidity providers (LPs). They must deposit ETH
and wZNN
into a pool in order to participate into the Orbital Program. Depending on how much liquidity they provide for the wZNN/ETH
pool on Uniswap, they will receive a proportional amount of ERC-20 LP tokens
. In the next step, the LP must swap the ERC-20 LP tokens
to the ZTS zLP tokens
(zLP
) on NoM using the decentralized cross-chain bridge. In order to become eligible for receiving dual-coin rewards from NoM's emission, the LP must deposit the zLP tokens
into the liquidity embedded contract. The liquidity embedded contract mirrors the staking embedded contract in terms of locking the tokens for a predefined time period. However, it differs from a rewards' perspective: participating LPs get both ZNN
and QSR
.
Assets
The bridge supports native assets as well as tokens from the source and destination networks.
Assets on NoM
ZTS
= native Zenon Token Standard asset on NoM e.g. ZenonZNN
, QuasarQSR
zEVM-20
= wrapped Zenon Token Standard asset on NoM e.g.zDAI
Assets on EVM networks
wZTS
= wrapped Zenon Token Standard asset on a particular destination network e.g.wZNN
asERC-20
EVM-20
= native EVM token on the EVM mainnet e.g.DAI
on Ethereum mainnet
Assets on non-EVM networks
- TBA
Assets on UTXO networks
- TBA
Classification
-
ZTS
andzEVM-20
assets are native toNoM
. -
EVM-20
andwZTS
assets are native to theEVM
network.
For example, an EVM-20
token can be:
ERC-20
for Ethereum mainnetBEP-20
for BNB Smart Chain
Decentralized Bridge
The purpose of the Decentralized Bridge is to connect different networks by wrapping and unwrapping assets.
Decentralized Bridge components:
- Bridge embedded contract on NoM
- Orchestrator Layer as middleware
- Smart Contracts on bridged network
EVM account model
At the moment, only account model EVM networks are supported, starting with the Ethereum mainnet.
Wrap assets
Source NoM -> Destination EVM
ZNN
(ZTS
on NoM) -> wrap ->wZNN
(ERC-20
on Ethereum)
Source EVM -> Destination NoM
DAI
(ERC-20
on Ethereum) -> wrap ->zDAI
(ZTS
on NoM)
Unwrap assets
Source EVM -> Destination NoM
wZNN
(ERC-20
on Ethereum) -> unwrap ->ZNN
(ZTS
on NoM)
Source NoM -> Destination EVM
zDAI
(ZTS
on NoM) -> unwrap ->DAI
(ERC-20
on Ethereum)
Core Contracts
The Core Contracts are one of the most important elements of the NoM Multi-chain infrastructure. They are deployed on NoM - the bridge embedded contract and each network that will participate in the multi-chain infrastructure. They are the primary infrastructure contracts, which the Orchestrator Nodes observe and which fundamentally enable the cross-chain communication. In general, Core Contracts have a similar structure and can be broken down to a receiving side, which we'll define later.
There are Core Contracts on each network that is part of the ecosystem, with the Orchestrator Layer acting as a global observer of inter-network events.
EVM Smart Contracts
The EVM smart contracts are specifically designed for Ethereum Virtual Machine
compatibility, including its specific secp256k1
elliptic curve.
EVM networks can be divided into layer-1
and layer-2
networks as follows:
Layer-1 EVM networks:
Integrated networks:
- Ethereum
- ChainID
1
- Currency
ETH
- ChainID
Upcoming integrations:
- BNB Smart Chain
- ChainID
56
- Currency
BNB
- ChainID
- Avalanche C-Chain
- ChainID
43114
- Currency
AVAX
- ChainID
- Fantom Opera
- ChainID
250
- Currency
FTM
- ChainID
- Celo
- ChainID
42220
- Currency
CELO
- ChainID
Layer-2 EVM networks:
Upcoming integrations:
- Arbitrum
- ChainID
42161
- Currency
ETH
- ChainID
- Polygon
- ChainID
137
- Currency
MATIC
- ChainID
- Optimism
- ChainID
10
- Currency
ETH
- ChainID
EVM Smart Contracts
The EVM smart contracts are deployed on the EVM networks integrated into the NoM Multi-chain Infrastructure.
Contract Anatomy
The code is written in Solidity v0.8.19
(latest as March 2023).
Imports
The smart contract uses the following openzeppelin
standard contracts:
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
-
using ECDSA for bytes32
- used to add therecover
ECDSA signature functionality -
using SafeERC20 for IERC20
- used to add thesafeTransfer
andsafeTransferFrom
functionalities -
contract Bridge is Context
- inherit_msgSender()
method to get the sender
Modifiers
-
onlyAdministrator
can only be called by owner of theadministrator
private key -
isNotHalted
can only be called if the bridge is not halted
Structs
-
TokenInfo
is used to store information about the bridged tokens -
RedeemInfo
is used for redeeming funds and information regarding time challenges
Events
event RegisteredRedeem(uint256 indexed nonce, address indexed to, address indexed token, uint256 amount);
event Redeemed(uint256 indexed nonce, address indexed to, address indexed token, uint256 amount);
event Unwrapped(address indexed from, address indexed token, string to, uint256 amount);
event Halted();
event Unhalted();
event RevokedRedeem(uint256 indexed nonce);
event PendingAdministrator(address indexed newAdministrator);
event SetAdministrator(address indexed newAdministrator, address oldAdministrator);
event PendingTss(address indexed newTss);
event SetTss(address indexed newTss, address oldTss);
event PendingGuardians();
event SetGuardians();
-
RegisteredRedeem
emitted when a redeem request is registered -
Redeemed
emitted when a redeem is completed -
Unwrapped
emitted when an unwrap request is registered -
Halted
emitted when the bridge is halted -
Unhalted
emitted when the bridge is unhalted -
RevokedRedeem
emitted when the administrator revokes an invalid redeem -
PendingAdministrator
emitted when a request for changing the administrator address is made -
SetAdministrator
emitted when the administrator address is set -
PendingTss
emitted when a request for changing the tss address is made -
SetTss
emitted when the tss address is set -
PendingGuardians
emitted when a request for changing the guardian addresses is made -
SetGuardians
emitted when the addresses of the guardians are set
Constants
-
uint256 constant uint256max
storestype(uint256).max
-
uint32 private constant networkClass
for EVM networks is hard coded to2
-
uint8 private constant minNominatedGuardians
must coincide with theMinGuardians
constant from the embedded contract and is hard coded to5
Variables
-
estimatedBlockTime
is set for each network depending on the block time interval; it is used by theorchestrator
to know how much to wait for one confirmation -
confirmationsToFinality
is the number of confirmations required to achieve finality for a given network; it is used by theorchestrator
to confirm an event -
halted
indicates if the bridge is halted or not -
allowKeyGen
indicates wether or not the tss address can be changed with a valid signature; theadmin
can always change the tss address -
administrator
is the EVM compatible address of theadmin
-
administratorDelay
is the delay required for changing theadmin
; it cannot be lower thanminAdministratorDelay
-
minAdministratorDelay
is the minimum delay required for changing theadmin
-
tss
is the TSS address jointly created during the key generation ceremony -
softDelay
is the delay required for the time challenge security primitive; it cannot be lower thanminSoftDelay
-
minSoftDelay
is the minimum delay required for the time challenge security primitive -
guardians
is the array containing the addresses of the guardians -
nominatedGuardians
is the array containing the addresses of the nominated guardians -
guardiansVotes
is the array containing the votes for the guardians -
votesCount
is a mapping containing the proposedadmin
votes of each guardian -
unhaltedAt
is the last block height at which the bridge was unhalted -
unhaltDuration
is the duration in blocks during which the bridge is still halted after theunhaltedAt
block height; it cannot be lower thanminUnhaltDuration
-
minUnhaltDuration
is the minimum duration in blocks during which the bridge is still halted after theunhaltedAt
block height -
actionsNonce
is the nonce required for a valid signature at a particular state of the bridge; must be always incremented after a signature is validated -
contractDeploymentHeight
is the block height at which the contract was deployed; it is used by theorchestrator
to know the height to scan events
Contract implementation
Constructor
In the constructor we set the following variables:
administrator
minUnhaltDuration
unhaltDuration
minAdministratorDelay
administratorDelay
minSoftDelay
softDelay
guardians
guardiansVotes
estimatedBlockTime
confirmationsToFinality
contractDeploymentHeight
redeem method
The first and the second step of the redeem process. During the first step a time challenge will start. During the second step, after softDelay
, the funds will be released/minted. The bridge must not be halted, the request must not have been revoked before, the token should be redeemable
and the TSS signature valid.
Parameters
to
- EVM address that will receive the fundstoken
-EVM-20
token addressamount
- amount of tokennonce
- unique identifier of the redeem requestsignature
- signature generated by the current TSS
Returns
- None
unwrap method
Register an unwrap request. Tokens will be locked/burned. The bridge must not be halted and the token must be bridgeable
.
Parameters
token
-EVM-20
token addressamount
- amount of tokento
- NoM address
Returns
- None
setTokenInfo method
Adds or edits an existing tokenInfo
. It contains information about permitted tokens to swap or redeem and their delays. Can be called only by the administrator
. Guarded by a time challenge.
Parameters
token
-EVM-20
token addressminAmount
- minimum amount of the token for unwrappingredeemDelay
- delay in blocks after the first redeem step in order to receive the fundsbridgeable
- whether the token can be unwrappedredeemable
- whether the token can be redeemedisOwned
- whether this contract has owner rights for theEVM-20
Returns
- None
halt method
Halts the network. It does not require a signature if called by the administrator
. Otherwise, a TSS signature is needed.
Parameters
signature
- current TSS signature
Returns
- None
unhalt method
Sets halted to false
and updates the haltedAt
block such that unhaltDelay
starts. Can only be called by the administrator
.
Parameters
- None
Returns
- None
revokeRedeems method
Revokes invalid redeem requests.
Parameters
nonces
- an array containing the unique identifiers for each request
Returns
- None
setAdministrator method
Changes the administrator
address. Can only be called by the administrator
. Guarded by a time challenge.
Parameters
newAdministrator
-new
administrator address
Returns
- None
setTss method
Changes the TSS address. If called by the administrator
, no signature is required and the time challenge starts. Otherwise, a valid TSS signature is required in order to validate the new address.
Parameters
newTss
-new
TSS addressoldSignature
- signature from the current TSSnewSignature
- signature from the new TSS
Returns
- None
emergency method
Sets administrator to address(0)
, TSS to address(0)
and halts the bridge. Can only be called by the administrator
. It enables guardians
to propose.
Parameters
- None
Returns
- None
nominateGuardians
Nominate the guardians
that are responsible to propose a new administrator in case of an emergency. Guarded by a time challenge. Can only be called by the administrator
.
Parameters
newGuardians
- an array containing the newguardian
addresses
Returns
- None
proposeAdministrator method
Will vote for a new administrator
address. Can only be called by a guardian
only if the bridge is in emergency state (the address of the administrator
is address(0)
).
Parameters
newAdministrator
- newadministrator
address
Returns
- None
setSoftDelay method
Sets the delay for the time challenge. Can only be called by the administrator
.
Parameters
delay
- delay in blocks
Returns
- None
setUnhaltDuration method
Sets the delay during which the bridge remains halted after calling unhalt
. Can only be called by the administrator
.
Parameters
duration
- duration in blocks
Returns
- None
setEstimatedBlockTime method
Sets the delay in which the bridge remains halted after calling unhalt
. Can only be called by the administrator
.
Parameters
blockTime
- block time in seconds; it is used by theorchestrator
layer
Returns
- None
setAllowKeyGen method
Sets allowKeyGen
to true that permits the TSS address to be changed by an address different from the administrator
. Can only be called by the administrator
.
Parameters
value
-true
orfalse
Returns
- None
setConfirmationsToFinality method
Sets the confirmations required by an event to be confirmed. Used by the orchestrator
layer. Can only be called by the administrator
.
Parameters
confirmations
- number of confirmations in blocks
Returns
- None
Unit Tests
TBA
Bridge Embedded Contract
The Bridge Embedded Contract is the embedded contract for the decentralized bridge deployed on the Network of Momentum.
Helper methods
CheckECDSASignature
method
Checks if the ECDSA signature is correct or returns error
in case it fails.
Parameters
message
- the message in[]byte
formatpubKeyStr
- the public key instring
formatsignatureStr
- the signature instring
format
Returns
bool
-true
if the signature passes,false
otherwise
CanPerformAction
method
Checks if the parameters of the bridge are correct or returns error
in case it fails.
Parameters
AccountVmContext
- current context of the VM
Returns
BridgeInfoVariable
- information regarding the bridgeOrchestratorInfo
- information regarding the orchestrator
CheckBridgeInitialized
method
Checks if the bridge is properly initialized or returns error
in case it fails.
Parameters
AccountVmContext
- current context of the VM
Returns
BridgeInfoVariable
- information regarding the bridge
CheckOrchestratorInfoInitialized
method
Checks if the orchestrator is properly initialized or returns error
in case it fails.
Parameters
AccountVmContext
- current context of the VM
Returns
OrchestratorInfo
- information regarding the orchestrator
CheckBridgeHalted
method
Checks if the bridge is halted or returns error
in case it fails.
Parameters
BridgeInfoVariable
- information regarding the bridgeAccountVmContext
- current context of the VM
Returns
nil
- the bridge is not halted
Contract implementation
The implementation of the Bridge Embedded Contract has a total of 20 methods that can be called by sending a specifically crafted account block:
WrapTokenMethod
method
Method for wrapping assets. If the bridge is initialized, not halted, the destination network and the token pair exists, than a wrap token request is created.
Parameters
NetworkClass
- the class of the destination networkChainId
- the chain identifier of the destination networkToAddress
- the address that can redeem the funds on the destination networkTokenStandard
- theZTS
used in thesend
blockAmount
- the amount used in thesend
block
Returns
AccountBlock
- only if the token is owned, a burn call to the token contract is performed that burns the received tokens
UpdateWrapRequestMethod
method
Method for updating the wrap request. If the signature
is valid and is generated by the TSS public key, it is saved in the wrap request signature field and can be used to redeem the funds.
Parameters
Id
- represents the id of a wrap requestsSignature
- a base64 encoded ECDSA signature used to redeem funds on the destination network
Returns
- None
UnwrapTokenMethod
method
Method for unwrapping assets. It is the first step in redeeming funds on NoM. Normally this method would be called by an orchestrator
node after a signing ceremony to register an unwrap request.
Parameters
NetworkClass
- the class of the source networkChainId
- the chain identifier of the source networkTransactionHash
- hash of the transaction on the source networkLogIndex
- log index in the block of the transaction that locked/burned the funds on the source network; together withtxHash
it creates a unique identifier for a transactionToAddress
- destination NoM addressTokenAddress
- address of the locked/burned token on the source networkAmount
- amount of token that was locked/burnedSignature
- the signature asbase64
encoded string of the unwrap request
Returns
- None
SetNetworkMethod
method
Method for setting a network. Used to add or edit an already existing bridged network.
Parameters
NetworkClass
- class of the networkChainId
- chain identifier of the networkName
-new
name of the networkContractAddress
-new
address the bridge contract was deployed toMetadata
-JSON
encoded string used in case theorchestrator
needs additional data for the network
Returns
- None
RemoveNetworkMethod
method
Method for removing a network uniquely identified by its class and chain identifier.
Parameters
NetworkClass
- class of the networkChainId
- chain identifier of the network
Returns
- None
SetNetworkMetadataMethod
method
Method for setting metadata for a network.
Parameters
NetworkClass
- class of the networkChainId
- chain identifier of the networkMetadata
-JSON
encoded string containing thenew
metadata
Returns
- None
SetTokenPairMethod
method
Method for setting a token pair for a network. It will add a new pair or edit an existing one; guarded by the time challenge primitive.
Parameters
- NetworkClass - network class of the network to add this pair to
- ChainId - chain identifier of the network to add this pair to
- TokenStandard - first component of the pair i.e.
ZTS
- TokenAddress - second component of the pair i.e.
EVM-20
Bridgeable
- boolean variable that specifies if theZTS
can be wrapped on NoMRedeemable
- boolean variable that specifies if theEVM-20
can be redeemed on NoMOwned
- boolean variable that specifies if the embedded bridge contract is the owner of theZTS
from the pair; if true, when wrapping the ZTS, the token will be burned, otherwise it will be lockedMinAmount
- minimum amount for wrapping theZTS
FeePercentage
- fee deducted from the amount when wrappingRedeemDelay
- delay in momentums until redeeming is possible on NoMMetadata
-JSON
encoded string containing metadata about the pair; used by theorchestrator
Returns
- None
RemoveTokenPairMethod
method
Method for removing a token pair for a network.
Parameters
NetworkClass
- class of the network that contains the pairChainId
- chain identifier of the network that contains the pairTokenStandard
-ZTS
of the pairTokenAddress
-EVM-20
address of the pair
Returns
- None
HaltMethod
method
Method for halting the bridge. If called by the administrator
it doesn't need a signature
, otherwise it needs a TSS signature with the current tssNonce
.
Parameters
Signature
-base64
encoded string containing the TSS signature
Returns
- None
UnhaltMethod
method
Method for unhalting the bridge. Can be called only by the administrator
.
Parameters
- None
Returns
- None
EmergencyMethod
method
Method for putting the bridge embedded contract into emergency mode. This method nullifies the administrator
address, tss public key and halts the bridge. It can be called in the extreme case when the administrator
private key has been compromised.
Parameters
- None
Returns
- None
ChangeTssECDSAPubKeyMethod
method
Method for changing the TSS public key. Guarded by time challenge when called by the administrator
. Otherwise it can be changed by the TSS using a signature from the current tss, one from the new tss and the new tss public key.
Parameters
PubKey
-base64
encoded string representing the new TSS public keyOldPubKeySignature
-base64
encoded string representing thechangeTss
message signed by the current TSSNewPubKeySignature
-base64
encoded string representing thechangeTss
message signed by corresponding private key
Returns
- None
ChangeAdministratorMethod
method
Method for changing the admin. Can be called only by the administrator
. Guarded by a time challenge with administratorDelay
.
Parameters
Address
- address of the newadministrator
Returns
- None
SetAllowKeygenMethod
method
Method that enables or disables the TSS key generation.
Parameters
Bool
-true
orfalse
value that indicates whether theorchestrator
nodes should start a key generation ceremony or not
Returns
- None
SetOrchestratorInfoMethod
method
Method for setting the information regarding the orchestrator layer.
Parameters
WindowSize
- size in momentums of a window used in theorchestrator
to determine which signing ceremony should occur, wrap or unwrap request and to determine the key sign ceremony timeoutKeyGenThreshold
- minimum number of participants of a key generation ceremonyConfirmationsToFinality
- minimum number of momentums to consider a wrap request confirmedEstimatedMomentumTime
- time in seconds between momentums
Returns
- None
SetBridgeMetadataMethod
method
Method for setting the metadata for the bridge.
Parameters
String
-JSON
encoded string containing additional information needed for theorchestrator
layer
Returns
- None
RevokeUnwrapRequestMethod
method
Method for revoking an unwrap request. This should be called if an unwrap request does not a have corresponding transaction on the source network that locks/burns the tokens.
Parameters
TransactionHash
- first component to uniquely identify an unwrap requestLogIndex
- second component to uniquely identify an unwrap request
Returns
- None
RedeemMethod
method
Method for redeeming assets. It is the second step in order to redeem funds after an unwrap request is created. In order to redeem the unwrap request the following conditions must be present: the bridge must not be halted, the network and token pair must exist and the request have not been redeemed or revoked before.
Parameters
TransactionHash
- first component to uniquely identify an unwrap requestLogIndex
- second component to uniquely identify an unwrap request
Returns
AccountBlock
- if theZTS
to be redeemed is owned, an account block to mint the amount will be sent to the token contract, otherwise a block sending the tokens will be sent to the user
NominateGuardiansMethod
method
Method for nominating guardians. Can only be called by the administrator
in order to propose new guardians
. Guarded by a time challenge. The number of guardian addresses must be higher than minGuardians
and each address in the array must be unique. ZeroAddress
is not accepted.
Parameters
[]Address
- contains the new guardian addresses
Returns
- None
ProposeAdministratorMethod
method
Method for proposing an admin. This method can only be called by a guardian
if the bridge is in emergency mode i.e. the administrator address is set to ZeroAddress
. After each guardian
votes for an address, the votes are counted and if there is a majority (50% + 1
), the administrator
will be set with that address.
Parameters
Address
- voted address
Returns
- None
Bridge Embedded Constants
Bridge constants are hard coded into the embedded.go
file as network constants.
-
InitialBridgeAdministrator
is the hard-coded address for the administration module, managed by the maintainers of the codebase asAddress
-
MaximumFee
is the maximum fee for a wrap request asuint32
; equivalent to100%
fee -
MinUnhaltDurationInMomentums
is the minimum amount of time, measured in momentums, until the bridge functionality is restored from a halted state asuint64
-
MinAdministratorDelay
is the minimum delay required by thetime challenge
foradmin
operations asuint64
-
MinSoftDelay
is the minimum delay required bytime challenge
for all operations excluding theadmin
and theguardians
asuint64
-
MinGuardians
is the minimum number of guardians required for the bridge to become operational asunit32
-
DecompressedECDSAPubKeyLength
is the size of the decompressedECDSA
public key inbytes
-
CompressedECDSAPubKeyLength
is the size of the compressedECDSA
public key inbytes
-
ECDSASignatureLength
is the size of theECDSA
signature inbytes
-
EdDSAPubKeyLength
is the size of theEdDSA
public key inbytes
InitialBridgeAdministrator = types.ParseAddressPanic("z1qz8q0x3rs36z2kw8eltf8r323hlcn64jnujkuz")
MaximumFee = uint32(10000)
MinUnhaltDurationInMomentums = uint64(6 * MomentumsPerHour) //main net
MinAdministratorDelay = uint64(2 * MomentumsPerEpoch) // main net
MinSoftDelay = uint64(MomentumsPerEpoch) // main net
MinGuardians = 5
DecompressedECDSAPubKeyLength = 65
CompressedECDSAPubKeyLength = 33
ECDSASignatureLength = 65
EdDSAPubKeyLength = 32
Bridge Embedded Error States
ErrUnknownNetwork = errors.New("unknown network")
ErrInvalidToAddress = errors.New("invalid destination address")
ErrBridgeNotInitialized = errors.New("bridge info is not initialized")
ErrOrchestratorNotInitialized = errors.New("orchestrator info is not initialized")
ErrTokenNotBridgeable = errors.New("token not bridgeable")
ErrNotGuardian = errors.New("sender is not a guardian")
ErrTokenNotRedeemable = errors.New("token not redeemable")
ErrBridgeHalted = errors.New("bridge is halted")
ErrInvalidRedeemPeriod = errors.New("invalid redeem period")
ErrInvalidRedeemRequest = errors.New("invalid request")
ErrInvalidTransactionHash = errors.New("invalid transaction hash")
ErrInvalidNetworkName = errors.New("invalid network name")
ErrInvalidContractAddress = errors.New("invalid contract address")
ErrInvalidToken = errors.New("invalid token standard or token address")
ErrTokenNotFound = errors.New("token not found")
ErrInvalidEDDSASignature = errors.New("invalid ed25519 signature")
ErrInvalidEDDSAPubKey = errors.New("invalid eddsa public key")
ErrInvalidECDSASignature = errors.New("invalid secp256k1 signature")
ErrInvalidDecompressedECDSAPubKeyLength = errors.New("invalid decompressed secp256k1 public key length")
ErrInvalidCompressedECDSAPubKeyLength = errors.New("invalid compressed secp256k1 public key length")
ErrNotAllowedToChangeTss = errors.New("changing the tss public key is not allowed")
ErrInvalidJsonContent = errors.New("metadata does not respect the JSON format")
ErrInvalidMinAmount = errors.New("invalid min amount")
ErrTimeChallengeNotDue = errors.New("time challenge not due")
ErrNotEmergency = errors.New("bridge not in emergency")
ErrInvalidGuardians = errors.New("invalid guardians")
ErrSecurityNotInitialized = errors.New("security not initialized")
ErrBridgeNotHalted = errors.New("bridge not halted")
Bridge Embedded JSON-RPC API
The JSON-RPC API
for the bridge embedded contract.
JSON-RPC API Methods
GetBridgeInfo
method
Returns the current bridge information or error
in case it fails.
Parameters
- None
Returns
BridgeInfoVariable
- the current bridge information
type BridgeInfoVariable struct {
// Administrator address
Administrator types.Address `json:"administrator"`
// ECDSA pub key generated by the orchestrator from key gen ceremony
CompressedTssECDSAPubKey string `json:"compressedTssECDSAPubKey"`
DecompressedTssECDSAPubKey string `json:"decompressedTssECDSAPubKey"`
// This specifies whether the orchestrator should key gen or not
AllowKeyGen bool `json:"allowKeyGen"`
// This specifies whether the bridge is halted or not
Halted bool `json:"halted"`
// Height at which the administrator called unhalt method, UnhaltDurationInMomentums starts from here
UnhaltedAt uint64 `json:"unhaltedAt"`
// After we call the unhalt embedded method, the bridge will still be halted for UnhaltDurationInMomentums momentums
UnhaltDurationInMomentums uint64 `json:"unhaltDurationInMomentums"`
// An incremental nonce used for signing messages
TssNonce uint64 `json:"tssNonce"`
// Additional metadata
Metadata string `json:"metadata"`
}
Example
// todo
GetSecurityInfo
method
Returns the current security information or error
in case it fails.
Parameters
- None
Returns
SecurityInfoVariable
- the current security information
// SecurityInfoVariable This refers to time challenge security
type SecurityInfoVariable struct {
// addresses that can vote for the new administrator once the bridge is in emergency
Guardians []types.Address `json:"guardians"`
// votes of the active guardians
GuardiansVotes []types.Address `json:"guardiansVotes"`
// delay upon which the new administrator or guardians will be active
AdministratorDelay uint64 `json:"administratorDelay"`
// delay upon which all other time challenges will expire
SoftDelay uint64 `json:"softDelay"`
}
Example
// todo
GetOrchestratorInfo
method
Returns the current orchestrator information or error
in case it fails.
Parameters
- None
Returns
OrchestratorInfo
- the current orchestrator information
type OrchestratorInfo struct {
// Momentums period in which only one signing ceremony (wrap or unwrap) can occur in the orchestrator
WindowSize uint64 `json:"windowSize"`
// This variable is used in the orchestrator to wait for at least KeyGenThreshold participants for a key gen ceremony
KeyGenThreshold uint32 `json:"keyGenThreshold"`
// Momentums until orchestrator can process wrap requests
ConfirmationsToFinality uint32 `json:"confirmationsToFinality"`
// Momentum time
EstimatedMomentumTime uint32 `json:"estimatedMomentumTime"`
// This variable is a reference for the orchestrator to check the last 24h of momentums for producing pillars
AllowKeyGenHeight uint64 `json:"allowKeyGenHeight"`
}
Example
// todo
GetTimeChallengesInfo
method
Returns a list of time challenges or error
in case it fails.
Parameters
- None
Returns
TimeChallengesList
- the current a list of time challenges
type TimeChallengesList struct {
Count int `json:"count"`
List []*definition.TimeChallengeInfo `json:"list"`
}
type TimeChallengeInfo struct {
MethodName string
ParamsHash types.Hash
ChallengeStartHeight uint64
}
Example
// todo
GetNetworkInfo
method
Returns the current network information or error
in case it fails.
Parameters
networkClass
- network class inuint32
formatchainId
- chain identifier inuint32
format
Returns
NetworkInfo
- the current network information.
// NetworkInfoVariable One network will always be znn, so we just need the other one
type NetworkInfoVariable struct {
NetworkClass uint32 `json:"networkClass"`
Id uint32 `json:"chainId"`
Name string `json:"name"`
ContractAddress string `json:"contractAddress"`
Metadata string `json:"metadata"`
TokenPairs [][]byte `json:"tokenPairs"`
}
Example
// todo
GetAllNetworks
method
Returns a list of all the available networks.
Parameters
pageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
format
Returns
NetworkInfoList
- a list of available networks
type NetworkInfoList struct {
Count int `json:"count"`
List []*definition.NetworkInfo `json:"list"`
}
Example
// todo
getToken
method
Returns a token by tokenStandard
or error
in case it fails.
Parameters
zts
- the Zenon Token Standard, inZenonTokenStandard
format
Returns
Token
- the current token information
type TokenInfo struct {
Owner types.Address `json:"owner"`
TokenName string `json:"tokenName"`
TokenSymbol string `json:"tokenSymbol"`
TokenDomain string `json:"tokenDomain"`
TotalSupply *big.Int `json:"totalSupply"`
MaxSupply *big.Int `json:"maxSupply"`
Decimals uint8 `json:"decimals"`
IsMintable bool `json:"isMintable"`
// IsBurnable = true implies that anyone can burn the token.
// The Owner can burn the token even if IsBurnable = false.
IsBurnable bool `json:"isBurnable"`
IsUtility bool `json:"isUtility"`
TokenStandard types.ZenonTokenStandard `json:"tokenStandard"`
}
Example
// todo
getRedeemableIn
method
Returns the number of momentums until an UnwrapTokenRequest
becomes redeemable.
Parameters
unwrapTokenRequest
- the unwrap token requesttokenPair
- the token pairmomentum
- the momentum
Returns
redeemableIn
- the number of momentums until anUnwrapTokenRequest
becomes redeemable inuint64
format
var redeemableIn uint64
Example
// todo
getConfirmationsToFinality
method
Returns the number of confirmations to finality for a WrapTokenRequest
or error
in case it fails.
Parameters
wrapTokenRequest
- the wrap request for a particular tokenconfirmationsToFinality
- the number of confirmations required to achieve finality inuint32
formatmomentum
- the momentum
Returns
actualConfirmationsToFinality
- the number of confirmations to achieve finality on the destination network inuint64
format
var actualConfirmationsToFinality uint64
Example
// todo
GetWrapTokenRequestById
method
Returns the token for the wrap request or error
in case it fails.
Parameters
id
- the hash of the wrap request, inHash
format
Returns
wrapTokenRequest
- the wrap token request inWrapTokenRequest
format
type WrapTokenRequest struct {
*definition.WrapTokenRequest
TokenInfo *api.Token `json:"token"`
ConfirmationsToFinality uint64 `json:"confirmationsToFinality"`
}
Example
// todo
GetAllWrapTokenRequests
method
Returns a list of tokens for all wrap requests or error
in case it fails.
Parameters
pageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
format
Returns
wrapTokenRequestList
- a list of wrap token requests
type WrapTokenRequestList struct {
Count int `json:"count"`
List []*WrapTokenRequest `json:"list"`
}
Example
// todo
GetAllWrapTokenRequestsByToAddress
method
Returns a list of wrap requests that match a particular address or error
in case it fails.
Parameters
pageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
formattoAddress
- the address instring
format
Returns
wrapTokenRequestList
- a list of wrap token requests
type WrapTokenRequestList struct {
Count int `json:"count"`
List []*WrapTokenRequest `json:"list"`
}
Example
// todo
GetAllWrapTokenRequestsByToAddressNetworkClassAndChainId
method
Returns a list of wrap requests that match a particular address, network class and chain identifier.
Parameters
toAddress
- the address instring
formatnetworkClass
- the network classpageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
format
Returns
wrapTokenRequestList
- a list of wrap token requests
type WrapTokenRequestList struct {
Count int `json:"count"`
List []*WrapTokenRequest `json:"list"`
}
Example
// todo
GetAllUnsignedWrapTokenRequests
method
Returns a list of unsigned wrap requests or error
in case it fails.
Parameters
pageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
format
Returns
wrapTokenRequestList
- a list of unsigned wrap token requests
Example
// todo
GetUnwrapTokenRequestByHashAndLog
method
Returns a list of unwrap token requests that match a particular Hash
and Log
or error
in case it fails.
Parameters
txHash
- the transaction hash inHash
formatlogIndex
- the log index inuint32
format
Returns
unwrapTokenRequest
- the unwrap token request
type UnwrapTokenRequest struct {
RegistrationMomentumHeight uint64 `json:"registrationMomentumHeight"`
NetworkClass uint32 `json:"networkClass"`
ChainId uint32 `json:"chainId"`
TransactionHash types.Hash `json:"transactionHash"`
LogIndex uint32 `json:"logIndex"`
ToAddress types.Address `json:"toAddress"`
TokenAddress string `json:"tokenAddress"`
TokenStandard types.ZenonTokenStandard `json:"tokenStandard"`
Amount *big.Int `json:"amount"`
Signature string `json:"signature"`
Redeemed uint8 `json:"redeemed"`
Revoked uint8 `json:"revoked"`
}
Example
// todo
GetAllUnwrapTokenRequests
method
Returns a list of all unwrap token requests or error
in case it fails.
Parameters
pageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
format
Returns
unwrapTokenRequestList
- a list of unwrap token requests
Example
// todo
GetAllUnwrapTokenRequestsByToAddress
method
Returns a list of all unwrap token requests that match a particular address.
Parameters
toAddress
- the address instring
formatpageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
format
Returns
unwrapTokenRequestList
- a list of unwrap token requests
Example
// todo
GetFeeTokenPair
method
Returns the fee for a particular token pair or error
in case it fails.
Parameters
zts
- the Zenon Token Standard, inZenonTokenStandard
format
Returns
ZtsFeesInfo
- ZTS fee information
type ZtsFeesInfo struct {
TokenStandard types.ZenonTokenStandard `json:"tokenStandard"`
AccumulatedFee *big.Int `json:"accumulatedFee"`
}
Example
// todo
Bridge Embedded Unit Tests
The unit tests are available here with 81.8%
code coverage.
Orchestrator Layer
The purpose of the Orchestrator Layer is to assure the off-chain communication and TSS signing of wrap and unwrap requests for the integrated networks.
OS support
Currently only Linux based operating systems are supported. This is due to the fact that Pillar nodes already running on public infrastructure have dedicated support for Linux based operating systems.
OS | Linux | Windows | MacOS |
---|---|---|---|
Yes | No | No |
Data directory
-
DefaultDataDir
is the default data directory for the orchestrator node located at~/.orchestrator
-
orchestrator
is executable file of the Orchestrator node -
config.json
is the configuration file
Configuration
Producer key
The Pillar operator must set his producer keyStore
in ~/.orchestrator
and provide the name
and passphrase
in config.json
After the first run, in config.json
, from producer key
an EVM address will automatically get generated and the field evmAddress
will be populated.
IMPORTANT: An ETH
deposit is mandatory for the generated evmAddress
that will be used as gas in case a halt
transaction is necessary to be performed on-chain.
Secrets
IMPORTANT: The Pillar operator must backup the ~/.orchestrator/tss
folder containing the generated TSS shard in case a hardware failure occurs. Without it, the node can no longer participate in the keysign
ceremonies, until it participates in another successful keygen
ceremony.
Ports
The default port is 55055
.
If you start with the default ports, please make sure that they are not occupied by other programs or blocked by the firewall.
netstat -nlp | grep 55055
Install from source
Go 1.20
or later is required. Check the Go documentation for more info.
go env
Build from source:
go build --ldflags '-extldflags "-Wl,--allow-multiple-definition"' -o ./orchestrator
orchestrator
service:
// todo
Connectors
Each Orchestrator Node is connected to both NoM and the supported destination network using the JSON-RPC API
. There are several types of connectors that provide different degrees of confidence for transaction finality.
Local Connectors
Full Node
The ideal configuration for an Orchestrator Node is to run its own full nodes for all supported networks. This way, it has a precise overview of the network state and does not rely to any third party that can be either maliciously corrupted or censored. Running full nodes also can detect chain reorganizations called reorgs
.
Example of chain reorgs for a Bitcoin full node running continuously since 17 December 2016:
- Actual reorgs: 4 (1 every 84,352 blocks / 570.3 days)
- Avoided reorgs: 174 (1 every 1,939 blocks / 13.1 days)
Light Node
Light Nodes decrease the load required to run a full node. Some implementations are better than others and if properly used can effectively displace the need for a full node.
Remote Connectors
Decentralized RPC Providers
Decentralized RPC Providers:
Decentralized RPC Providers should only be used for redundancy purposes.
Centralized RPC Providers
Centralized RPC Providers:
- Infura
- Alchemy
- Quicknode
Centralized RPC Providers should only be used for redundancy purposes.
Protocol Level Liquidity
The purpose of the Protocol Level Liquidity is to distribute dual-coin liquidity rewards in ZNN
and QSR
to eligible Liquidity Providers.
Liquidity Embedded Contract
The Liquidity Embedded Contract is the embedded contract for the Orbital Program deployed on the Network of Momentum.
Contract implementation
The implementation of the Liquidity Embedded Contract has a total of 14 methods that can be called by sending a specifically crafted account block:
UpdateEmbeddedLiquidityMethod
method
Method for updating the embedded liquidity contract.
Parameters
- None
Returns
- None
SetTokenTupleMethod
method
Method for setting a token tuple and their corresponding reward percentages for the Orbital Program. Can only be set by the administrator
.
Parameters
TokenStandards
- an array containing theZTS
allowed for stakingZnnPercentages
- an array containing theZNN
percentage rewards for eachZTS
in theTokenStandards
arrayQsrPercentages
- an array containing theQSR
percentage rewards for eachZTS
in theTokenStandards
arrayMinAmounts
- an array containing the minimum amounts for staking eachZTS
in theTokenStandards
array
Returns
- None
LiquidityStakeMethod
method
Method for staking the liquidity for the Orbital Program.
Parameters
stakeTime
- stake time in seconds that should be a multiple of number in seconds for a monthtokenStandard
- fetched from the send blockamount
- fetched from the send block
Returns
- None
CancelLiquidityStakeMethod
method
Method for cancelling the liquidity stake for the Orbital Program.
Parameters
id
- a hash that uniquely identifies the stake entry to be canceled
Returns
- None
UpdateRewardEmbeddedLiquidityMethod
method
Method to be called when the Liquidity Contract is updated. It contains the new mechanism for distributing dual-coin rewards.
Parameters
- None
Returns
- None
SetIsHalted
method
Method for halting or unhalting the liquidity staking. Can only be called by the administrator
.
Parameters
bool
-true
orfalse
Returns
- None
UnlockLiquidityStakeEntries
method
Method for unlocking the liquidity staking entries for a ZTS
that is no longer allowed for staking.
Parameters
tokenStandard
- fetched from the send block
Returns
- None
SetAdditionalReward
method
Method for setting an additional reward for the liquidity staking. Can only be called by the administrator
.
Parameters
znnRewards
- additionalZNN
rewards for the next epochsqsrRewards
- additionalQSR
rewards for the next epochs
Returns
- None
ChangeAdministratorLiquidity
method
Method for changing the administrator
for the liquidity embedded contract. Can only be called by the administrator
. Guarded by a time challenge.
Parameters
address
- address of thenew
administrator
Returns
- None
NominateGuardiansLiquidity
method
Method for nominating the guardians
for the liquidity embedded contract. Can only be called by the Administrator
. Guarded by a time challenge.
Parameters
[]address
- an array containing the new addresses
Returns
- None
ProposeAdministratorLiquidity
method
Method for proposing a new administrator
for the liquidity embedded contract. Can only be called by a guardian
if the embedded liquidity contract is in an emergency state.
Parameters
address
- voted address
Returns
- None
EmergencyLiquidity
method
Method for putting the liquidity embedded contract into emergency mode. Can only be called by the administrator
.
Parameters
- None
Returns
- None
Liquidity Embedded JSON-RPC API
The JSON-RPC API
for the liquidity embedded contract.
JSON-RPC API Methods
GetLiquidityInfo
method
Returns the current liquidity information or error
in case it fails.
Parameters
- None
Returns
LiquidityInfo
- the current bridge information
type LiquidityInfo struct {
Administrator types.Address `json:"administrator"`
IsHalted bool `json:"isHalted"`
ZnnReward *big.Int `json:"znnReward"`
QsrReward *big.Int `json:"qsrReward"`
TokenTuples []TokenTuple `json:"tokenTuples"`
}
Example
// todo
GetSecurityInfo
method
Returns the current security information or error
in case it fails.
Parameters
- None
Returns
SecurityInfoVariable
- the current security information
// SecurityInfoVariable This refers to time challenge security
type SecurityInfoVariable struct {
// addresses that can vote for the new administrator once the bridge is in emergency
Guardians []types.Address `json:"guardians"`
// votes of the active guardians
GuardiansVotes []types.Address `json:"guardiansVotes"`
// delay upon which the new administrator or guardians will be active
AdministratorDelay uint64 `json:"administratorDelay"`
// delay upon which all other time challenges will expire
SoftDelay uint64 `json:"softDelay"`
}
Example
// todo
GetLiquidityStakeEntriesByAddress
method
Returns the current liquidity staking entries by address
or error
in case it fails.
Parameters
address
- the address inAddress
formatpageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
format
Returns
LiquidityStakeList
- the current liquidity staking list
type LiquidityStakeList struct {
TotalAmount *big.Int `json:"totalAmount"`
TotalWeightedAmount *big.Int `json:"totalWeightedAmount"`
Count int `json:"count"`
Entries []*definition.LiquidityStakeEntry `json:"list"`
}
Example
// todo
GetUncollectedReward
method
Returns the RewardDeposit
for a particular address
or error
in case it fails.
Parameters
address
- the address inAddress
format
Returns
RewardDeposit
- the current uncollected reward deposit
type RewardDeposit struct {
Address *types.Address `json:"address"`
Znn *big.Int `json:"znnAmount"`
Qsr *big.Int `json:"qsrAmount"`
}
Example
// todo
GetFrontierRewardByPage
method
Returns the RewardHistoryList
for a particular address
or error
in case it fails.
Parameters
address
- the address inAddress
formatpageIndex
- the page index inuint32
formatpageSize
- the size of the page inuint32
format
Returns
RewardHistoryList
- the current reward history list
type RewardHistoryList struct {
Count int64 `json:"count"`
List []*RewardHistoryEntry `json:"list"`
}
Example
// todo
GetTimeChallengesInfo
method
Returns a list of time challenges or error
in case it fails.
Parameters
- None
Returns
TimeChallengesList
- the current a list of time challenges
type TimeChallengesList struct {
Count int `json:"count"`
List []*definition.TimeChallengeInfo `json:"list"`
}
type TimeChallengeInfo struct {
MethodName string
ParamsHash types.Hash
ChallengeStartHeight uint64
}
Example
// todo
Liquidity Embedded Constants
Liquidity constants are hard coded into the embedded.go
file as network constants.
-
LiquidityZnnTotalPercentages
represent the maximum sum for theZNN
percentage rewards of each allowedZTS
-
LiquidityQsrTotalPercentages
represent the maximum sum for theQSR
percentage rewards of each allowedZTS
-
LiquidityStakeWeights
represent the liquidity staking weights depending on the number of months a user locks the liquidity
LiquidityZnnTotalPercentages uint32 = 10000
LiquidityQsrTotalPercentages uint32 = 10000
LiquidityStakeWeights = []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
}
Liquidity Embedded Error States
ErrInvalidPercentages = errors.New("invalid percentages")
ErrInvalidRewards = errors.New("invalid liquidity stake rewards")
Liquidity Embedded Unit Tests
The unit tests are available here with 74.5%
code coverage.
License
The implementation is fully open source on Github with a permissive licensing model - GNU General Public License v3.0
to allow builders to develop a healthy middleware ecosystem for the Network of Momentum by integrate more networks.
Security
The philosophy underpinning the architecture is based on the Law of Action-Reaction. There can be no effect without a cause: every redeem transaction processed by the bridge must adhere to this causality principle. This means that funds must be locked
/burned
on the source network in order to be redeemed
on the destination network.
Time-challenge security primitive
Every sensitive action is split into two separate stages and is safeguarded by a time-challenge security primitive. This primitive is used throughout the codebase for every sensitive action that either involves moving funds or other critical actions.
Additionally, the two step procedure is enforced in both wrapping or unwrapping assets:
-
REQUEST: this action signals the intention of a user to wrap or unwrap his assets.
-
REDEEM: this action settles the user's request and actually delivers the swapped assets to its corresponding address.
After the redeem request is created, there is a window
during which the funds are unredeemable. Also during this window
, the orchestrator nodes will check if there is a corresponding transaction on the source network that locks
/burns
the funds. In case it doesn't exist, the orchestrator nodes will start the halting process of the bridge.
Realtime Monitoring
The NoM Multi-chain infrastructure project expects all participants to develop and maintain their own security monitoring strategies. This expectation is based on the value of having heterogeneous monitoring strategies across the Guardian set as a function of Wormhole's defense in depth approach, increasing the likelihood of detecting fraudulent activity.
Pillar operators participating in the Orchestrator Layer (running orchestrator nodes) should aim to capture all of the following domains with their monitoring strategies:
- Orchestrator node monitoring: TSS ceremonies, peer-to-peer messages, logs, etc.
- Blockchain node monitoring: transaction activity, peer-to-peer messages, reorgs, logs, etc.
- Smart Contracts activity: on-chain state, emitted events, etc.
- Administrator Module activity: on-chain state
- Social media monitoring
- Bug bounty program
- Github security reporting
- Audit findings
- Forum thread
The orchestrator layer has a powerful built-in logging library.
Lastly, if any user detects a security event via their monitoring system, they are urged to engage with the Pillar operators
or the admin
in order to activate the emergency state
.
Emergency Mode
The emergency mode for the decentralized bridge is designed to prevent any damage should a failure occurs. Only the administrator can put the bridge on each network in an emergency state.
There are 4 possible states in total:
LiveState uint8 = 0
KeyGenState uint8 = 1
HaltedState uint8 = 2
EmergencyState uint8 = 3
Distributed Halting Mechanism
The decentralized bridge has a built-in distributed halting mechanism that will halt it in case it observes an event on a destination network that has no corresponding event on the source network. Concretely, redeem requests without lock/burn associated transactions will trigger a signing ceremony to halt the bridge on each network. Only the administrator and the orchestrator nodes can call the halting procedure via the dedicated halt method.
Guardians Voting System
In the extreme case that the bridge is in emergency state the administrator address becomes null
. A new administrator must be voted by the guardians in order to restore functionality.
Once a voted address reaches a quorum of 50% + 1
votes out of the total number of guardians, it becomes the new administrator.
Deployed Contracts
Here you can find the addresses for the deployed core contracts on all the networks that the NoM Multi-chain Infrastructure supports, including testnet deployments.
Mainnet Deployments
Mainnet Core Contracts
Network name | Network Class | Chain ID | Contract Address |
---|---|---|---|
Network of Momentum | 1 | 1 | |
Ethereum | 2 | 1 | TBA |
Binance Smart Chain | 2 | 56 | TBA |
Avalanche (C-Chain) | 2 | 43114 | TBA |
Fantom | 2 | 250 | TBA |
Celo | 2 | 42220 | TBA |
Arbitrum | 2 | 42161 | TBA |
Polygon | 2 | 137 | TBA |
Optimism | 2 | 10 | TBA |
Bitcoin | 3 | N/A | N/A |
Litecoin | 3 | N/A | N/A |
Testnet Deployments
Testnet Core Contracts
Network name | Network Class | Chain ID | Contract Address |
---|---|---|---|
Network of Momentum | 1 | 1 | |
Ethereum | 2 | 1 | TBA |
Binance Smart Chain | 2 | 56 | TBA |
Avalanche (C-Chain) | 2 | 43114 | TBA |
Fantom | 2 | 250 | TBA |
Celo | 2 | 42220 | TBA |
Arbitrum | 2 | 42161 | TBA |
Polygon | 2 | 137 | TBA |
Optimism | 2 | 10 | TBA |
Bitcoin | 3 | N/A | N/A |
Litecoin | 3 | N/A | N/A |
Audits
The core components of the NoM multi-chain infrastructure (go-tss and tss-lib libraries) are properly audited are are used in production by high ranking cryptocurrencies like Thorchain.
- Thorchain go-tss
- Binance tss-lib
- IPFS libp2p security considerations and Denial of Service mitigation strategies