BondingManager

Git Source

Inherits: AgentManager, InterfaceBondingManager

BondingManager keeps track of all existing agents on the Synapse Chain. It utilizes a dynamic Merkle Tree to store the agent information. This enables passing only the latest merkle root of this tree (referenced as the Agent Merkle Root) to the remote chains, so that the agents could "register" themselves by proving their current status against this root. BondingManager is responsible for the following:

  • Keeping track of all existing agents, as well as their statuses. In the MVP version there is no token staking, which will be added in the future. Nonetheless, the agent statuses are still stored in the Merkle Tree, and the agent slashing is still possible, though with no reward/penalty for the reporter/reported.
  • Marking agents as "ready to be slashed" once their fraud is proven on the local or remote chain. Anyone could complete the slashing by providing the proof of the current agent status against the current Agent Merkle Root.
  • Sending Manager Message to remote LightManager to withdraw collected tips from the remote chain.
  • Accepting Manager Message from remote LightManager to slash agents on the Synapse Chain, when their fraud is proven on the remote chain.

State Variables

summit

address public summit;

_agentMap

mapping(address => AgentStatus) private _agentMap;

_domainAgents

mapping(uint32 => address[]) private _domainAgents;

_agents

address[] private _agents;

_agentTree

DynamicTree private _agentTree;

Functions

constructor

constructor(uint32 synapseDomain_) MessagingBase("0.0.3", synapseDomain_);

initialize

function initialize(address origin_, address destination_, address inbox_, address summit_) external initializer;

addAgent

Adds a new agent for the domain. This is either a fresh address (Inactive), or an agent who used to be active on the same domain before (Resting).

Inactive: proof should be the proof of inclusion of an empty leaf having index following the last added agent in the tree.

function addAgent(uint32 domain, address agent, bytes32[] memory proof) external onlyOwner;

Parameters

NameTypeDescription
domainuint32Domain where the Agent will be active
agentaddressAddress of the Agent
proofbytes32[]Merkle proof of the Inactive/Resting status for the agent

initiateUnstaking

Initiates the unstaking of the agent bond. Agent signature is immediately no longer considered valid on Synapse Chain, and will be invalid on other chains once the Light Manager updates their agent merkle root on these chains.

proof should be the proof of inclusion of the agent leaf with Active flag having index previously assigned to the agent.

function initiateUnstaking(uint32 domain, address agent, bytes32[] memory proof) external onlyOwner;

Parameters

NameTypeDescription
domainuint32Domain where the Agent is active
agentaddressAddress of the Agent
proofbytes32[]Merkle proof of the Active status for the agent

completeUnstaking

Completes the unstaking of the agent bond. Agent signature is no longer considered valid on any of the chains.

proof should be the proof of inclusion of the agent leaf with Unstaking flag having index previously assigned to the agent.

function completeUnstaking(uint32 domain, address agent, bytes32[] memory proof) external onlyOwner;

Parameters

NameTypeDescription
domainuint32Domain where the Agent was active
agentaddressAddress of the Agent
proofbytes32[]Merkle proof of the unstaking status for the agent

resolveDisputeWhenStuck

Allows contract owner to resolve a stuck Dispute. This could only be called if no fresh data has been submitted by the Notaries to the Inbox, which is required for the Dispute to be resolved naturally.

Will revert if any of these is true:

  • Caller is not contract owner.
  • Domain doesn't match the saved agent domain.
  • slashedAgent is not in Dispute.
  • Less than FRESH_DATA_TIMEOUT has passed since the last Notary submission to the Inbox.
function resolveDisputeWhenStuck(uint32 domain, address slashedAgent) external onlyOwner onlyWhenStuck;

Parameters

NameTypeDescription
domainuint32
slashedAgentaddressAgent that is being slashed

completeSlashing

Completes the slashing of the agent bond. Agent signature is no longer considered valid under the updated Agent Merkle Root.

proof should be the proof of inclusion of the agent leaf with Active/Unstaking flag having index previously assigned to the agent.

function completeSlashing(uint32 domain, address agent, bytes32[] memory proof) external;

Parameters

NameTypeDescription
domainuint32Domain where the Agent was active
agentaddressAddress of the Agent
proofbytes32[]Merkle proof of the active/unstaking status for the agent

remoteSlashAgent

Remote AgentManager should call this function to indicate that the agent has been proven to commit fraud on the origin chain.

This initiates the process of agent slashing. It could be immediately completed by anyone calling completeSlashing() providing a correct merkle proof for the OLD agent status. Note: as an extra security check this function returns its own selector, so that Destination could verify that a "remote" function was called when executing a manager message. Will revert if msgOrigin is equal to contract's local domain.

function remoteSlashAgent(uint32 msgOrigin, uint256 proofMaturity, uint32 domain, address agent, address prover)
    external
    returns (bytes4 magicValue);

Parameters

NameTypeDescription
msgOriginuint32
proofMaturityuint256
domainuint32Domain where the slashed agent was active
agentaddressAddress of the slashed Agent
proveraddressAddress that initially provided fraud proof to remote AgentManager

Returns

NameTypeDescription
magicValuebytes4Selector of this function

withdrawTips

Withdraws locked base message tips from requested domain Origin to the recipient. Issues a call to a local Origin contract, or sends a manager message to the remote chain.

Could only be called by the Summit contract.

function withdrawTips(address recipient, uint32 origin_, uint256 amount) external;

Parameters

NameTypeDescription
recipientaddressAddress to withdraw tips to
origin_uint32
amountuint256Tips value to withdraw

agentRoot

Returns the latest known root of the Agent Merkle Tree.

function agentRoot() external view override returns (bytes32);

getActiveAgents

Returns all active agents for a given domain.

function getActiveAgents(uint32 domain) external view returns (address[] memory agents);

Parameters

NameTypeDescription
domainuint32Domain to get agents from (ZERO for Guards)

agentLeaf

Returns a leaf representing the current status of agent in the Agent Merkle Tree.

Will return an empty leaf, if agent is not added to the tree yet.

function agentLeaf(address agent) external view returns (bytes32 leaf);

Parameters

NameTypeDescription
agentaddressAgent address

Returns

NameTypeDescription
leafbytes32Agent leaf in the Agent Merkle Tree

leafsAmount

Returns a total amount of leafs representing known agents.

This includes active, unstaking, resting and slashed agents. This also includes an empty leaf as the very first entry.

function leafsAmount() external view returns (uint256 amount);

getProof

Returns a proof of inclusion of the agent in the Agent Merkle Tree.

Will return a proof for an empty leaf, if agent is not added to the tree yet. This proof could be used by ANY next new agent that calls {addAgent}.

function getProof(address agent) external view returns (bytes32[] memory proof);

Parameters

NameTypeDescription
agentaddressAgent address

Returns

NameTypeDescription
proofbytes32[]Merkle proof for the agent

allLeafs

Returns a full list of leafs from the Agent Merkle Tree.

This might consume a lot of gas, do not use this on-chain.

function allLeafs() public view returns (bytes32[] memory leafs);

getLeafs

Returns a list of leafs from the Agent Merkle Tree with indexes [indexFrom .. indexFrom + amount).

This might consume a lot of gas, do not use this on-chain.

function getLeafs(uint256 indexFrom, uint256 amount) public view returns (bytes32[] memory leafs);

_updateLeaf

Updates value in the Agent Merkle Tree to reflect the newStatus. Will revert, if supplied proof for the old value is incorrect.

function _updateLeaf(bytes32 oldValue, bytes32[] memory proof, AgentStatus memory newStatus, address agent) internal;

_notifyDisputeOpened

Notify local AgentSecured contracts about the opened dispute.

function _notifyDisputeOpened(uint32 guardIndex, uint32 notaryIndex) internal override;

_notifyDisputeResolved

Notify local AgentSecured contracts about the resolved dispute.

function _notifyDisputeResolved(uint32 slashedIndex, uint32 rivalIndex) internal override;

_storedAgentStatus

Returns the status of the agent.

function _storedAgentStatus(address agent) internal view override returns (AgentStatus memory);

_getAgent

Returns agent address for the given index. Returns zero for non existing indexes.

function _getAgent(uint256 index) internal view override returns (address agent);

_getIndex

Returns the index of the agent in the Agent Merkle Tree. Returns zero for non existing agents.

function _getIndex(address agent) internal view override returns (uint256 index);

_getLeaf

Returns the current leaf representing agent in the Agent Merkle Tree.

function _getLeaf(address agent) internal view returns (bytes32 leaf);

_getLeaf

Returns a leaf from the Agent Merkle Tree with a given index.

function _getLeaf(uint256 index) internal view returns (bytes32 leaf);