BondingManager
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
Name | Type | Description |
---|---|---|
domain | uint32 | Domain where the Agent will be active |
agent | address | Address of the Agent |
proof | bytes32[] | 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
Name | Type | Description |
---|---|---|
domain | uint32 | Domain where the Agent is active |
agent | address | Address of the Agent |
proof | bytes32[] | 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
Name | Type | Description |
---|---|---|
domain | uint32 | Domain where the Agent was active |
agent | address | Address of the Agent |
proof | bytes32[] | 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
Name | Type | Description |
---|---|---|
domain | uint32 | |
slashedAgent | address | Agent 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
Name | Type | Description |
---|---|---|
domain | uint32 | Domain where the Agent was active |
agent | address | Address of the Agent |
proof | bytes32[] | 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
Name | Type | Description |
---|---|---|
msgOrigin | uint32 | |
proofMaturity | uint256 | |
domain | uint32 | Domain where the slashed agent was active |
agent | address | Address of the slashed Agent |
prover | address | Address that initially provided fraud proof to remote AgentManager |
Returns
Name | Type | Description |
---|---|---|
magicValue | bytes4 | Selector 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
Name | Type | Description |
---|---|---|
recipient | address | Address to withdraw tips to |
origin_ | uint32 | |
amount | uint256 | Tips 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
Name | Type | Description |
---|---|---|
domain | uint32 | Domain 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
Name | Type | Description |
---|---|---|
agent | address | Agent address |
Returns
Name | Type | Description |
---|---|---|
leaf | bytes32 | Agent 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
Name | Type | Description |
---|---|---|
agent | address | Agent address |
Returns
Name | Type | Description |
---|---|---|
proof | bytes32[] | 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);