-
Notifications
You must be signed in to change notification settings - Fork 3
Chainbridge working
The chain bridge contracts (Bridge.sol, GenericHandler.sol ..) are deployed on all of the connected chains. The off chain relayer is configured to listen to Deposit
events from these contracts and relays them to other chains.
Each instance of Bridge.sol
deployed on a particular chain is created with a chainID
(This is not to be confused with the blockchain's chainID). The chainID
is an identifier at the chain bridge system level and can be set by the Bridge admin at the time of contract deployment. It's used by the offchain relayer to keep track of messages between chains (sourceChainID
and destinationChainID
).
When a user triggers a cross-chain transaction through chain bridge, they invoke Bridge.deposit with a destinaitonChainID
, resourceID
and data
(data contains the transaction information abi encoded and packed).
The Bridge contract is pre-configured by the Bridge administrator to map all deposits with a particular resourceID
to the invoke a specific contract and function selector on transaction initiation and completion. In our case we've preconfigured the bridge as follows:
resourceID | chain | initiation | completion |
---|---|---|---|
reportRebaseResourceID | base-chain |
AMPLChainBridgeGateway validateRebaseReport
|
- |
reportRebaseResourceID | satellite-chain | - |
ChainBridgeXCAmpleGateway reportRebase
|
transferResourceID | base-chain |
AMPLChainBridgeGateway validateAndLock
|
AMPLChainBridgeGateway unlock
|
transferResourceID | satellite-chain |
ChainBridgeXCAmpleGateway validateAndBurn
|
ChainBridgeXCAmpleGateway mint
|
The data packing logic can be found as part of the SDK.
const createGenericDepositData = (hexMetaData) => {
if (hexMetaData === null) {
return '0x' + toHex(0, 32).substr(2);
}
const hexMetaDataLength = hexMetaData.substr(2).length / 2;
return '0x' + toHex(hexMetaDataLength, 32).substr(2) + hexMetaData.substr(2);
};
const packXCRebaseData = (epoch, totalSupply) => {
return createGenericDepositData(
AbiCoder.encode(['uint256', 'uint256'], [epoch, totalSupply]),
);
};
const packXCTransferData = (depositor, recipient, amount, totalSupply) => {
return createGenericDepositData(
AbiCoder.encode(
['address', 'address', 'uint256', 'uint256'],
[depositor, recipient, amount, totalSupply],
),
);
};
It can be triggered by any user on the base chain (ethereum).
User invokes Bridge.deposit
with:
reportRebaseResourceID
destinationChainID
-
data
: The currentepoch
andtotalSupply
abi encoded and packed.
The validateRebaseReport
function performs a data integrity check if the reported rebase information (epoch and supply) as part of the deposit
transaction is the same as the current value on chain. If successful it emits a Deposit
event which relayers pick up and transmit to the satellite chain.
NOTE: For a n-way bridge between a base chain and n-1 sat chains. reportRebase
needs to be triggered n-1 times with every destinationChainID
. The ChainBridgeBatchRebaseReport utility performs this in 1 transaction.
On the satellite chain the reportRebase
function updates the new totalSupply
and epoch
on the XCAmpleController
contract, after which rebase
can be executed on the sat chain.
BaseChain (initiation):
user -> Bridge.deposit(destinationChainID, transferResourceID, data) -> GenericHandler.deposit -> AMPLChainBridgeGateway.validateRebaseReport
SatelliteChain (completion):
relayer -> Bridge.executeProposal(chainID, data, resourceID) -> GenericHandler.deposit -> ChainBridgeXCAmpleGateway.reportRebase -> XCAmpleController.reportRebase
It can be triggered by any user on either the base chain (ethereum) or any satellite chain.
User invokes Bridge.deposit
with:
transferResourceID
destinationChainID
-
data
: Thedepositor
,recipient
amount
andtotalSupply
abi encoded and packed.
BaseChain (initiation):
user -> approves TokenVault contract
user -> Bridge.deposit(destinationChainID, transferResourceID, data) -> GenericHandler.deposit -> AMPLChainBridgeGateway.validateAndLock -> TokenVault.lock
SatelliteChain (completion):
relayer -> Bridge.executeProposal(chainID, data, resourceID) -> GenericHandler.deposit -> ChainBridgeXCAmpleGateway.mint -> XCAmpleController.mint -> XCAmple.mint
SatelliteChain (initiation):
user -> approves XCAmpleController contract
user -> Bridge.deposit(destinationChainID, transferResourceID, data) -> GenericHandler.deposit -> ChainBridgeXCAmpleGateway.validateAndBurn -> XCAmpleController.burn -> XCAmple.burn
BaseChain (completion):
relayer -> Bridge.executeProposal(chainID, data, resourceID) -> GenericHandler.deposit -> AMPLChainBridgeGateway.unlock -> TokenVault.unlock