Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System registries #87

Merged
merged 13 commits into from
Aug 11, 2022
13 changes: 3 additions & 10 deletions packages/contracts/contracts/AttestationCollector.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import { AuthManager } from "./auth/AuthManager.sol";
import { Attestation } from "./libs/Attestation.sol";
import { TypedMemView } from "./libs/TypedMemView.sol";
import { NotaryRegistry } from "./NotaryRegistry.sol";
import { GlobalNotaryRegistry } from "./registry/GlobalNotaryRegistry.sol";

import {
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

contract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {
contract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {
using Attestation for bytes29;
using TypedMemView for bytes;
using TypedMemView for bytes29;
Expand Down Expand Up @@ -175,7 +174,7 @@ contract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable
external
returns (bool attestationStored)
{
(address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);
(address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);
attestationStored = _storeAttestation(_notary, _view);
if (attestationStored) {
// Emit Event only if the Attestation was stored
Expand All @@ -187,12 +186,6 @@ contract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable
▏*║ INTERNAL FUNCTIONS ║*▕
\*╚══════════════════════════════════════════════════════════════════════╝*/

function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {
return _isNotary(_homeDomain, _notary);
}

function _isWatchtower(address _watchtower) internal view override returns (bool) {}

function _formatAttestation(
uint32 _domain,
uint32 _nonce,
Expand Down
44 changes: 18 additions & 26 deletions packages/contracts/contracts/Home.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ pragma solidity 0.8.13;

// ============ Internal Imports ============
import { Version0 } from "./Version0.sol";
import { UpdaterStorage } from "./UpdaterStorage.sol";
import { AuthManager } from "./auth/AuthManager.sol";
import { DomainNotaryRegistry } from "./registry/DomainNotaryRegistry.sol";
import { GuardRegistry } from "./registry/GuardRegistry.sol";
import { Attestation } from "./libs/Attestation.sol";
import { MerkleLib } from "./libs/Merkle.sol";
import { Header } from "./libs/Header.sol";
import { Message } from "./libs/Message.sol";
import { Tips } from "./libs/Tips.sol";
import { SystemMessage } from "./system/SystemMessage.sol";
import { SystemContract } from "./system/SystemContract.sol";
import { MerkleTreeManager } from "./Merkle.sol";
import { IUpdaterManager } from "./interfaces/IUpdaterManager.sol";
import { TypeCasts } from "./libs/TypeCasts.sol";
Expand All @@ -27,7 +28,7 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol";
* Accepts submissions of fraudulent signatures
* by the Updater and slashes the Updater in this case.
*/
contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {
contract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {
// ============ Libraries ============

using Attestation for bytes29;
Expand Down Expand Up @@ -114,14 +115,17 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {

// ============ Constructor ============

constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks
constructor(uint32 _localDomain)
SystemContract(_localDomain)
DomainNotaryRegistry(_localDomain)
{} // solhint-disable-line no-empty-blocks

// ============ Initializer ============

function initialize(IUpdaterManager _updaterManager) public initializer {
// initialize queue, set Updater Manager, and initialize
__SystemContract_initialize();
_setUpdaterManager(_updaterManager);
__SynapseBase_initialize(updaterManager.updater());
_addNotary(updaterManager.updater());
state = States.Active;
// insert a historical root so nonces start at 1 rather then 0. Here we insert the default root of a sparse merkle tree
historicalRoots.push(hex"27ae5ba08d7291c96c8cbddcc148bf48a6d68c7974b94356f53754ef6171d757");
Expand Down Expand Up @@ -153,7 +157,8 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {
* @param _updater the new Updater
*/
function setUpdater(address _updater) external onlyUpdaterManager {
_setUpdater(_updater);
// TODO: do this properly
trajan0x marked this conversation as resolved.
Show resolved Hide resolved
_addNotary(_updater);
// set the Home state to Active
// now that Updater has been rotated
state = States.Active;
Expand Down Expand Up @@ -259,7 +264,7 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {
*/
function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {
// This will revert if signature is not valid
(address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);
(address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);
uint32 _nonce = _view.attestationNonce();
bytes32 _root = _view.attestationRoot();
// Check if nonce is valid, if not => update is fraud
Expand All @@ -270,8 +275,8 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {
}
// Signed root is not the same as the historical one => update is fraud
}
_fail();
emit ImproperAttestation(_updater, _attestation);
_fail(_notary);
emit ImproperAttestation(_notary, _attestation);
return true;
}

Expand All @@ -291,12 +296,13 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {
* @notice Slash the Updater and set contract state to FAILED
* @dev Called when fraud is proven (Improper Update or Double Update)
*/
function _fail() internal {
function _fail(address _notary) internal {
// TODO: remove Failed state
trajan0x marked this conversation as resolved.
Show resolved Hide resolved
// set contract to FAILED
state = States.Failed;
// slash Updater
updaterManager.slashUpdater(payable(msg.sender));
emit UpdaterSlashed(updater, msg.sender);
emit UpdaterSlashed(_notary, msg.sender);
}

/**
Expand All @@ -315,20 +321,6 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {
return (uint64(_destination) << 32) | _nonce;
}

function _isUpdater(uint32 _homeDomain, address _updater)
internal
view
override
returns (bool)
{
require(_homeDomain == localDomain, "Wrong domain");
return _updater == updater;
}

function _isWatchtower(address) internal pure override returns (bool) {
return false;
}

/**
* @notice Returns "adjusted" sender address.
* @dev By default, "sender address" is msg.sender.
Expand Down
44 changes: 26 additions & 18 deletions packages/contracts/contracts/ReplicaManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
pragma solidity 0.8.13;

// ============ Internal Imports ============
import { UpdaterStorage } from "./UpdaterStorage.sol";
import { AuthManager } from "./auth/AuthManager.sol";
import { GlobalNotaryRegistry } from "./registry/GlobalNotaryRegistry.sol";
import { GuardRegistry } from "./registry/GuardRegistry.sol";
import { Attestation } from "./libs/Attestation.sol";
import { Version0 } from "./Version0.sol";
import { ReplicaLib } from "./libs/Replica.sol";
Expand All @@ -13,6 +13,7 @@ import { Header } from "./libs/Header.sol";
import { Tips } from "./libs/Tips.sol";
import { TypeCasts } from "./libs/TypeCasts.sol";
import { SystemMessage } from "./system/SystemMessage.sol";
import { SystemContract } from "./system/SystemContract.sol";
import { IMessageRecipient } from "./interfaces/IMessageRecipient.sol";
// ============ External Imports ============
import { TypedMemView } from "./libs/TypedMemView.sol";
Expand All @@ -22,7 +23,7 @@ import { TypedMemView } from "./libs/TypedMemView.sol";
* @notice Track root updates on Home,
* prove and dispatch messages to end recipients.
*/
contract ReplicaManager is Version0, UpdaterStorage, AuthManager {
contract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {
// ============ Libraries ============

using ReplicaLib for ReplicaLib.Replica;
Expand Down Expand Up @@ -76,9 +77,17 @@ contract ReplicaManager is Version0, UpdaterStorage, AuthManager {
uint256 newConfirmAt
);

event AttestationAccepted(
uint32 indexed homeDomain,
uint32 indexed nonce,
bytes32 indexed root,
bytes signature
);

// ============ Constructor ============

constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}
//solhint-disable-next-line no-empty-blocks
constructor(uint32 _localDomain) SystemContract(_localDomain) {}

// ============ Initializer ============

Expand All @@ -94,7 +103,8 @@ contract ReplicaManager is Version0, UpdaterStorage, AuthManager {
* @param _updater The EVM id of the updater
*/
function initialize(uint32 _remoteDomain, address _updater) public initializer {
__SynapseBase_initialize(_updater);
__SystemContract_initialize();
_addNotary(_remoteDomain, _updater);
// set storage variables
entered = 1;
activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);
Expand Down Expand Up @@ -136,7 +146,7 @@ contract ReplicaManager is Version0, UpdaterStorage, AuthManager {
* @param _attestation Attestation data and signature
*/
function submitAttestation(bytes memory _attestation) external {
(, bytes29 _view) = _checkUpdaterAuth(_attestation);
(, bytes29 _view) = _checkNotaryAuth(_attestation);
uint32 remoteDomain = _view.attestationDomain();
require(remoteDomain != localDomain, "Update refers to local chain");
uint32 nonce = _view.attestationNonce();
Expand All @@ -146,15 +156,20 @@ contract ReplicaManager is Version0, UpdaterStorage, AuthManager {
replica.setConfirmAt(newRoot, block.timestamp);
// update nonce
replica.setNonce(nonce);
emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());
emit AttestationAccepted(
ChiTimesChi marked this conversation as resolved.
Show resolved Hide resolved
remoteDomain,
nonce,
newRoot,
_view.attestationSignature().clone()
);
}

/**
* @notice First attempts to prove the validity of provided formatted
* `message`. If the message is successfully proven, then tries to process
* message.
* @dev Reverts if `prove` call returns false
* @param _message Formatted message (refer to UpdaterStorage.sol Message library)
* @param _message Formatted message (refer to Message library)
* @param _proof Merkle proof of inclusion for message's leaf
* @param _index Index of leaf in home's merkle tree
*/
Expand Down Expand Up @@ -219,8 +234,9 @@ contract ReplicaManager is Version0, UpdaterStorage, AuthManager {
* been relayed before calling. Only callable by owner (Governance)
* @param _updater New Updater
*/
function setUpdater(address _updater) external onlyOwner {
_setUpdater(_updater);
function setUpdater(uint32 _domain, address _updater) external onlyOwner {
// TODO: proper implementation
_addNotary(_domain, _updater);
}

/**
Expand Down Expand Up @@ -321,14 +337,6 @@ contract ReplicaManager is Version0, UpdaterStorage, AuthManager {
return abi.decode(_returnData, (string)); // All that remains is the revert string
}

function _isUpdater(uint32, address _updater) internal view override returns (bool) {
return _updater == updater;
}

function _isWatchtower(address) internal pure override returns (bool) {
return false;
}

function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {
// Check if SYSTEM_SENDER was specified as message recipient
if (_recipient == SystemMessage.SYSTEM_SENDER) {
Expand Down
116 changes: 0 additions & 116 deletions packages/contracts/contracts/UpdaterStorage.sol

This file was deleted.

Loading