The home for Hyperlane core contracts, sdk packages, and other infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hyperlane-monorepo/solidity/contracts/Home.sol

98 lines
2.6 KiB

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;
import "./Common.sol";
import "./Merkle.sol";
import "./Queue.sol";
contract Home is MerkleTreeManager, QueueManager, Common {
using QueueLib for QueueLib.Queue;
using MerkleLib for MerkleLib.Tree;
mapping(uint32 => uint32) public sequences;
4 years ago
uint256 constant BOND_SIZE = 50 ether;
event Dispatch(
uint32 indexed destination,
uint32 indexed sequence,
// the message is after this root. Some future update will contain it.
bytes32 indexed current,
bytes message
);
event ImproperUpdate();
constructor(
uint32 _originSLIP44,
address _updater,
bytes32 _current
)
4 years ago
payable
MerkleTreeManager()
QueueManager()
Common(_originSLIP44, _updater, _current)
{
4 years ago
require(msg.value >= BOND_SIZE, "insufficient bond");
}
function fail() internal override {
_setFailed();
4 years ago
msg.sender.transfer(address(this).balance / 2);
}
function enqueue(
uint32 destination,
bytes32 recipient,
bytes memory body
) external notFailed {
uint32 sequence = sequences[destination] + 1;
sequences[destination] = sequence;
bytes32 _digest =
Message.messageHash(
originSLIP44,
bytes32(uint256(uint160(msg.sender))),
sequence,
destination,
recipient,
body
);
tree.insert(_digest);
queue.enqueue(root());
emit Dispatch(destination, sequence, current, body);
}
function update(
bytes32 _oldRoot,
bytes32 _newRoot,
bytes memory _signature
) external notFailed {
if (improperUpdate(_newRoot, _oldRoot, _signature)) return;
while (true) {
bytes32 next = queue.dequeue();
if (next == _newRoot) break;
}
4 years ago
emit Update(_oldRoot, _newRoot, _signature);
}
function improperUpdate(
bytes32 _oldRoot,
bytes32 _newRoot,
bytes memory _signature
) public notFailed returns (bool) {
require(Common.checkSig(_newRoot, _oldRoot, _signature), "bad sig");
require(_oldRoot == current, "Not a current update");
if (!queue.contains(_newRoot)) {
fail();
emit ImproperUpdate();
return true;
}
return false;
}
function suggestUpdate() external view returns (bytes32, bytes32) {
return (current, queue.lastItem());
}
}